1.methods 方法
通过 v-on:事件类型() 绑定方法 括号里面可以传递多个参数也可以不传参数
<button @click="del(index)">删除</button>
<button v-if="key == 'num'" @click="min(item.num,index)"> - </button>
在methods 里面做数据处理
methods: {
// 传入当前数据的值和索引 通过索引操作arr里面的num数据
min(num, index) {
if (num - 1 >= 1) {
this.arr[index].num--
} else if (confirm("确认删除吗?")) {
this.arr.splice(index, 1)
}
},
max(num, index) {
// console.log(num, index);
this.arr[index].num++
},
del(index) {
// 删除数据的核心 通过传递index下标使用splice方法删除数组里面的数据
// console.log(index);
if (confirm("确认删除吗?")) {
this.arr.splice(index, 1)
}
}
},
2.computed 计算属性
必须使用return返回数据
直接在页面使用这个属性
数据加载完成自动更新一次并且存储数据 在数据发生改变的时候自动进行刷新
<td colspan="6">总价:{
{sum | money}}</td>
在computed里面处理数据
computed: {
sum() {
let sum = 0
for (var i = 0; i < this.arr.length; i++) {
// console.log(this.arr[i].price);
sum += this.arr[i].price * this.arr[i].num
}
return sum
}
},
get()方法和set()方法
效果:输入姓和名拼接到姓名里面 在姓名里面输入拆分到姓和名
<div id="app">
姓:<input type="text" v-model.lizy.trim="inp1">
名:<input type="text" v-model.lizy.trim="inp2">
<br>
姓名:<input type="text" v-model.lizy.trim="inp3">
</div>
使用get()获取数据进行修改
使用set()达到反向修改数据的目的
computed: {
// inp3() {
// console.log(this.inp1 + this.inp2);
// return this.inp1 + this.inp2
// }
inp3: {
// 只读 页面数据发生改变 计算属性才改变
get() {
return this.inp1 + this.inp2
},
// 计算属性里面的数据改变页面的也改变
set(val) {
let arr = val.split("")
let [
a,
...b
] = arr
// b通过解构出来是数组 然后通过join转为字符串
// console.log(a, b.join(""));
this.inp1 = a || ""
this.inp2 = b.join("") || ""
}
}
},
3.filter 过滤器
必须使用return 返回数据
使用管道符 | 隔开 可以使用多个过滤器 注意顺序
<!-- 使用多个注意顺序 先数字类型计算再做字符串拼接 -->
<!-- 10打五折 5 -->
<p>{
{money | getmoney(5) | sum}}</p>
<!-- 20打8折 16 -->
<p>{
{money2 | getmoney(8) | sum}}</p>
内容上使用
{
{item2 | nomover(key)}}
属性上使用
<a :href="item.href | urltop($data._this)">{
{item.name}}</a><br>
在filter里面处理数据 可以传递多个参数
默认参数就是 | 左边的值 第二个值开始就是传递的参数
// 过滤器 中的this指向window
filters: {
// val参数默认参数 就是|前面的值
getgender(val) {
// 必须使用return 返回结果
if (val == '0') {
return "女"
} else if (val == '1') {
return "男"
} else {
return "保密"
}
},
getage(age) {
if (age => 18) {
return "已成年"
} else {
return "未成年"
}
},
// 过滤器使用多个参数
getmoney(moneys, dis) {
// 打折 根据上面传递的参数打不同的折第一个参数是默认|前面的值
// 第二个参数就是上面自己写的参数 设置为打的折数
return moneys * (dis / 10)
},
// 添加¥符号和加 .00
sum(money) {
return '¥' + money + '.00'
},
// 设置统一的网址开头
urltop(url, i) {
console.log(i);
return `${i.http}${url}`
}
}
使用上面的方法做的购物栏效果
使用map和filter方法
data(){
return {
// 状态数据
checks: [false, false, false, false],
}
}
computed: {
// 全选/不全选
checkAll: {
get() {
// 如果有一个为false就为false
return !this.checks.includes(false);
},
set(newVal) {
// 修改全部的为当前相同的状态
return (this.checks = this.checks.map(() => {
return newVal;
}));
},
},
// 计算勾选的总价
sum() {
// var money = 0;
// this.checks.forEach((item, index) => {
// if (item) {
// return (money += this.books[index].price * this.books[index].num);
// }
// });
// return money;
let total = this.books.reduce((pre, item, index) => {
return pre + (this.checks[index] ? item.price * item.num : 0);
}, 0);
return total;
},
},
watch: {},
methods: {
// 增加
add(index, item) {
// 通过下标修改
// this.books[index].num++;
// 直接修改当前传递过来的数量
item.num++;
},
// 减少
del(index) {
if (this.books[index].num > 1) {
this.books[index].num--;
}
},
},
完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
table,
tr,
td,
th {
border: 2px solid black;
text-align: center;
/* width: 600px; */
padding: 5px 10px;
}
table {
border-collapse: collapse;
margin: 0 auto;
}
</style>
</head>
<body>
<div id="app">
<table>
<!-- 表头 -->
<thead>
<tr>
<!-- 遍历表头里的数据 -->
<th v-for="item in title">
{
{item}}
</th>
</tr>
<!-- 数据 -->
<tbody>
<!-- 循环遍历数组里的对象 页面和数据双向绑定-->
<tr v-for="item,index in arr" :key="item.id">
<!-- 遍历对象里的数据 -->
<td v-for="item2,key in item">
<!-- 如果key的值不是num 就不显示 -->
<button v-if="key == 'num'" @click="min(item.num,index)"> - </button>
<!-- 给数据做了过滤 给价格栏加¥和.00 只渲染价格栏 不是价格的就不渲染 -->
{
{item2 | nomover(key)}}
<!-- 给不是价格的数据进行渲染 -->
{
{item2 | moneys(key)}}
<!-- 如果key的值不是num 就不显示 -->
<button v-if="key== 'num'" @click="max(item.num,index)"> + </button>
</td>
<td>
<!-- 在操作下面添加删除-->
<button @click="del(index)">删除</button>
</td>
</tr>
</tbody>
</thead>
<tr>
<td colspan="6">总价:{
{sum | money}}</td>
</tr>
</table>
</div>
<script>
// 实例化vue对象
const app = new Vue({
el: "#app", //实例化vue对象的绑定内容
data: {
// 购物车数据
arr: [{
id: 1,
name: "算发导论",
year: "2006 - 9",
price: 85,
num: 1
},
{
id: 2,
name: "UNIX编程艺术",
year: "2006 - 2",
price: 59,
num: 1
},
{
id: 3,
name: "Vue程序设计",
year: "2008 - 10",
price: 35,
num: 1
},
{
id: 4,
name: "颈椎康复",
year: "2006 - 3",
price: 129,
num: 1
},
],
// 表头数据
title: [
"编号", "书籍名称", "出版日期", "价格", "购买数量", "操作"
],
},
methods: {
// 传入当前数据的值和索引 通过索引操作arr里面的num数据
min(num, index) {
if (num - 1 >= 1) {
this.arr[index].num--
} else if (confirm("确认删除吗?")) {
this.arr.splice(index, 1)
}
},
max(num, index) {
// console.log(num, index);
this.arr[index].num++
},
del(index) {
// console.log(index);
if (confirm("确认删除吗?")) {
this.arr.splice(index, 1)
}
}
},
filters: {
// 只读属性 当变量使用
money(val) {
return "¥" + val + ".00"
},
moneys(val, key) {
console.log(val);
if (key == "price") {
return "¥" + val + ".00"
}
},
nomover(val, key) {
if (key != "price") {
return val
}
}
},
computed: {
sum() {
let sum = 0
for (var i = 0; i < this.arr.length; i++) {
// console.log(this.arr[i].price);
sum += this.arr[i].price * this.arr[i].num
}
return sum
}
},
});
</script>
</body>
</html>
4.功能升级vue版
计算勾选的商品价格 通过checked判断
<template lang="">
<div class="shopcar">
<div>
<h1>购物车<span>编辑</span></h1>
</div>
<!-- 如果购物车为空就显示该图片 -->
<div class="img" v-if="false">
<img src="../../public/img/0.png" alt="" width="100%" />
</div>
<!-- 购物车内容 -->
<div v-else>
<ul class="list">
<li v-for="(item, index) in list" :key="item.id">
<input
class="checked"
type="checkbox"
ref="checked"
@click="checked"
/>
<img src="../../public/img/c1.png" alt="" />
<p class="p1">{
{ item.title }}</p>
<p class="p2">{
{ item.text }}</p>
<p class="p3">
{
{ item.money * item.num }}¥.00
<i class="iconfont icon-shanchu" @click="del(item.id)">删除</i>
</p>
<p class="p4">
<button @click="add(-1, item.id)">-</button>
<input type="text" v-model="item.num" />
<button @click="add(1, item.id)">+</button>
</p>
</li>
</ul>
</div>
<!-- 底部 -->
<div class="bottom">
<input
name="checkbox"
value="Item 1"
type="checkbox"
class="tui-checkbox"
@click="checkeds"
ref="checkeds"
/>
<span class="s1" ref="text">全选</span>
<span class="s3">结算</span>
<span class="s2"> 合计:{
{ money }}¥</span>
</div>
</div>
</template>
<script>
export default {
// 组件注册
components: {},
mixins: [],
props: [],
data() {
return {
money: 0,
sum: 1,
list: [
{
id: 1,
title: "喜羊羊薯片",
text: "薯片好吃的一批,吃了每天都喜羊羊",
money: 15,
img: "../../public/img/c1.png",
num: 1,
},
{
id: 2,
title: "懒羊羊薯片",
text: "薯片好吃的一批,吃了每天都懒羊羊",
money: 15,
img: "../../public/img/c1.png",
num: 2,
},
{
id: 3,
title: "灰太狼薯片",
text: "薯片好吃的一批,吃了每天都动力十足",
money: 15,
img: "../../public/img/c1.png",
num: 3,
},
],
};
},
watch: {
// money: function (val) {
// console.log(val);
// var checkeda = this.$refs.checked;
// console.log(checkeda);
// for (var i = 0; i < this.list.length; i++) {
// if (checkeda[i].checked) {
// val += this.list[i].money * this.list[i].num;
// }
// }
// },
},
computed: {
// 总价
// money() {
// var num = 0;
// // for (var i = 0; i < this.list.length; i++) {
// // num += this.list[i].money * this.list[i].num;
// // }
// return num;
// },
},
// 加减
methods: {
add(val, id) {
// console.log(val);
// console.log(id);
this.list.forEach((item, index) => {
if (item.id == id) {
// console.log(item.num);
if (item.num >= 1) {
item.num += val;
}
if (item.num - 1 < 1) {
item.num = 1;
}
}
});
this.num();
},
// 删除
del(id) {
// console.log(id);
this.list.forEach((item, index) => {
if (item.id == id) {
// console.log(index);
// console.log(this.list[index]);
this.list.splice(index, 1);
}
});
this.num();
},
// 全选
checkeds() {
// console.log(this.$refs.checked.length);
var checkeda = this.$refs.checked;
var checkeds = this.$refs.checkeds;
for (var i = 0; i < checkeda.length; i++) {
checkeda[i].checked = checkeds.checked;
}
var text = this.$refs.text;
text.innerText = checkeds.checked ? "全不选" : "全选";
this.num();
},
// 单个
checked(e) {
// console.log(e.target);
var checkeda = this.$refs.checked;
var checkeds = this.$refs.checkeds;
// console.log(checkeda.length);
checkeds.checked = true;
for (var i = 0; i < checkeda.length; i++) {
if (!checkeda[i].checked) {
checkeds.checked = false;
}
}
var text = this.$refs.text;
text.innerText = checkeds.checked ? "全不选" : "全选";
this.num();
},
// 总价 计算勾选的商品价格
num() {
var num = 0;
var checkeda = this.$refs.checked;
// console.log(checkeda);
for (var i = 0; i < this.list.length; i++) {
if (checkeda[i].checked) {
num += this.list[i].money * this.list[i].num;
}
}
this.money = num;
},
},
// 生命周期 - 创建完成(访问当前this实例)
created() {},
// 生命周期 - 挂载完成(访问DOM元素)
mounted() {},
destroyed() {},
};
</script>
<style lang="less" scoped>
//设置选中背景
.tui-checkbox:checked {
background: #1673ff;
}
//设置复选框样式
.tui-checkbox {
margin-top: 10px;
width: 25px;
height: 25px;
background-color: #ffffff;
border: solid 1px #dddddd;
-webkit-border-radius: 50%;
border-radius: 50%;
font-size: 0.8rem;
margin-top: 20px;
padding: 0;
position: relative;
display: inline-block;
vertical-align: top;
cursor: default;
-webkit-appearance: none;
-webkit-user-select: none;
user-select: none;
-webkit-transition: background-color ease 0.1s;
transition: background-color ease 0.1s;
}
//设置伪类,即显现的对勾样式
.tui-checkbox:checked::after {
content: "";
top: 5px;
left: 5px;
position: absolute;
background: transparent;
border: #fff solid 2px;
border-top: none;
border-right: none;
height: 6px;
width: 10px;
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.shopcar {
background-color: #f7f6fb;
.img {
margin: auto;
}
div {
text-align: center;
width: 100%;
background-color: #fff;
h1 {
font-size: 35px;
text-align: center;
padding: 20px;
padding-left: 50px;
span {
font-size: 25px;
margin-top: 10px;
float: right;
}
}
}
.bottom {
position: absolute;
bottom: 60px;
// background-color: red;
font-size: 20px;
height: 60px;
line-height: 60px;
span {
display: inline-block;
}
.s1 {
margin-left: 5px;
font-size: 16px;
}
.s2 {
margin-right: 20px;
float: right;
font-size: 16px;
}
.s3 {
margin-right: 20px;
float: right;
color: #f7f6fb;
margin-top: 5px;
line-height: 40px;
overflow: hidden;
padding: 5px;
display: inline-block;
background-color: #fc0050;
width: 100px;
border-radius: 30px;
}
}
}
.list {
display: flex;
flex-direction: column;
justify-content: flex-start;
li {
background-color: #eee;
padding: 5px;
padding-top: 15px;
margin: 5px;
.checked {
float: left;
margin-top: 40px;
margin-right: 10px;
}
img {
width: 50px;
float: left;
}
p {
text-align: left;
text-indent: 1em;
margin-bottom: 10px;
}
.p1 {
font-size: 20px;
color: #ff7716;
}
.p2 {
font-size: 14px;
}
.p3 {
font-size: 18px;
color: rgb(247, 91, 0);
i {
float: right;
color: #000;
font-weight: 700;
margin-right: 20px;
}
}
.p4 {
float: right;
margin-right: 50px;
input {
text-align: center;
width: 30px;
margin: 2px;
}
}
}
}
</style>