在之前的学习中都是给一些基本的元素(button、view)绑定了元素 ,但从来没给每个循环元素绑定过
list: [{ name: '奥特曼1', num: 6, price: 50, id: 1, status: false, }, { name: '奥特曼2', num: 5, price: 30, id: 2, status: false, }, { name: '奥特曼3', num: 8, price: 16, id: 3, status: false, }], 商品名称 {{item.name}} 数量 {{item.num}} 价钱 ¥{{item.price}}
上面是一组基础数据 我们要实现点击哪个组 就拿到哪组的数据 记得给谁绑定谁就会生效,绑定了点击事件 记得要在methods里面定义哈
getItem(item, index) {
console.log(item, index);
},
注意在循环中 我们是可以把循环的变量当做参数传给 methods里定义的方法里的, 注意传过去的参数 和接受的参数 要对应
getItem(item, index) { console.log(item, index); },
可以看到从上面 点击哪个值 在控制台就可以打印出对应的值
二、修改数组对象中的某个值这时候有一个场景哈 如果让你实现点击哪一项让当前的哪一项 的价钱加1你会怎么做
先来说一种错误写法 直接修改item里面的变量 让里面的价钱+1
getItem(item, index) {
item.price = item.price + 1
},
本质上是可以这么修改的,但是不推荐哈,原因就是 传过来的对象和data里面定义的对象 指向的都是同一个地址,所以可以修改,如果你去定义一个简单的数据类型
// template{{num}} //data: num: 0, // methods add(num) { num=num+1 },
如果你试过的话 你会发现这么修改简单数据类型并没有任何作用,原因是简单数据类型没有地址的概念 现在修改的num是一个简单数据类型传过来的 num 并非data里定义的 num 传过来的只是值而已
如果你想修改变量的话 直接赋值data里的变量即可
add(num) {
this.num = this.num + 1
},
如果你想直接修改 复杂数据类型里的某个值 也是同理,我们既然可以拿到上面的索引 直接根据索引找某个值就好了
getItem(item, index) {
console.log(item, index);
// 1. 第一种写法 拿到list对应的当前项的值去+1
this.list[index].price = this.list[index].price + 1
},
getItem(item, index) {
console.log(item, index);
// 2. 第二种写法 拿到item 当前项的值去+1
this.list[index].price = item.price + 1
},
三、切换变量小demo
//data list: [{ name: '奥特曼1', num: 6, price: 50, id: 1, status: false, }, { name: '奥特曼2', num: 5, price: 30, id: 2, status: false, }, { name: '奥特曼3', num: 8, price: 16, id: 3, status: false, }], 商品名称 {{item.name}} 数量 {{item.num}} 价钱 ¥{{item.price}}
我们想呢 点击哪个按钮 就让谁切换它的状态,看上面的数据哈 每一项都有一个status 你就可以根据索引拿到当前的状态赋值 做法就是取反哈!
toggleStatus(item, index) {
this.list[index].status = !item.status
},
四、计算选中的价格
我们还是通过上面定义的点击事件哈
1.先不考虑当前选没选中 先把所有的价钱算出来
错误写法:
toggleStatus(item, index) {
this.list[index].status = !item.status
this.list.forEach(it=>this.allPrice = it.price*it.num)
},
这么写的话永远拿的都是 最后一次循环的值 每次都在替换 知道替换到最后一次 变成了128
正确写法:
this.list.forEach(it=> this.allPrice = this.allPrice + it.price*it.num)
这样写呢 就会把之前把之前计算过的带着再算一次
这样我们就可以拿到 所有的价钱哈
2.计算选中的
我们想要的并不是所有的总价钱 肯定是拿到选中的
第一种写法
toggleStatus(item, index) {
this.list[index].status = !item.status
// 第一种写法
this.allPrice = 0
this.list.forEach((it, idx) => {
if (it.status == true) {
this.allPrice = this.allPrice + it.price * it.num
}
})
},
记得每次都赋值一下初始值哈,如果 你不知道什么原因 我建议你把赋值一行代码注释了 看看有没有什么影响
第二种写法
toggleStatus(item, index) {
this.list[index].status = !item.status
// 思路:把选中的数组过滤出来 再去计算
let arr = this.list.filter(item=> item.status) // 把选中的数组过滤出来 赋值给arr
let sum = 0 // 算出总价钱用的
arr.forEach(it=> sum = sum + it.price * it.num) //计算价钱
this.allPrice = sum // 赋值给上面的变量
console.log('总价钱',sum,'当前选中的数组',arr);
},
四、computed
computed 计算属性通常适合做一些映射、多对一时进行的操作,多对一:例如 一个数组中 判断每项算出一个结果出来
语法:
computed: {
getAllPrice() {
return this.num+1
}
},
我们来看vue 给我提供的例子
{{ message.split('').reverse().join('') }}
上面呢 在一个差值表达式里调用了很多方法 如果说在上面操作中在加一些方法会不会感觉很凌乱,所以vue提供给我们了计算属性,它会实时根据data里的变量实时映射
{{reverseStr}}
computed: {
reverseStr(){
return this.str.split('').reverse().join('')
}
},
例如通过上面例子中计算总价格 我们就可以通过计算属性去实现它
getAllPrice() {
return this.list.filter(it => it.status).reduce((acc, it) => acc + it.price * it.num, 0)
},
reduce 的执行过程
五、watch
watch监听 他会实时监听这某一个、或某一组值的变化
简单数据类型监听
watch: {
num(newValue, oldValue) {
console.log('num新值:',newValue, 'num旧值',oldValue);
// 做一些操作代码
this.watchNum = newValue + 999
}
}
复杂数据类型
watch: {
list:{
deep:true, // 开启深度监听 专门对付复杂数据类型
immediate:true, // 首次监听 一打开页面就想监听
handler: function (newValue, oldValue){
this.watchAllPrice = 0
this.list.forEach((it, idx) => {
if (it.status == true) {
this.watchAllPrice = this.watchAllPrice + it.price * it.num
}
})
}
}
},
注意:handler的函数格式不要写成箭头函数,否则拿不到当前的vue实例
总结 :watch能做的computed都可以实现,如果说你发现了哪个好玩的功能点 可以考虑试一下这两个是否都能实现呢
扩展:watch和computed 的区别



