一、给数组绑定点击事件
在之前的学习中都是给一些基本的元素(button、view)绑定了元素 ,但从来没给每个循环元素绑定过
<view class="box1 flexA" v-for="(item,index) in list" @click="getItem(item,index)">
<view class="" style="margin-left: 100rpx;">
<view class="flexJ" style="width: 400rpx;">
<view class="">商品名称 </view>
<view class="">{{item.name}}</view>
</view>
<view class="flexJ" style="width: 400rpx;">
<view class="">数量</view>
<view class="">{{item.num}}</view>
</view>
<view class="flexJ" style="width: 400rpx;">
<view class="">价钱</view>
<view class="">¥{{item.price}}</view>
</view>
</view>
</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,
}],
上面是一组基础数据 我们要实现点击哪个组 就拿到哪组的数据 记得给谁绑定谁就会生效,绑定了点击事件 记得要在methods里面定义哈
getItem(item, index) {
console.log(item, index);
},
注意在循环中 我们是可以把循环的变量当做参数传给 methods里定义的方法里的, 注意传过去的参数 和接受的参数 要对应
<view class="box1 flexA" v-for="(item,index) in list" @click="getItem(item,index)"></view>
getItem(item, index) {
console.log(item, index);
},
可以看到从上面 点击哪个值 在控制台就可以打印出对应的值
二、修改数组对象中的某个值
这时候有一个场景哈 如果让你实现点击哪一项让当前的哪一项 的价钱加1你会怎么做
先来说一种错误写法 直接修改item里面的变量 让里面的价钱+1
getItem(item, index) {
item.price = item.price + 1
},
本质上是可以这么修改的,但是不推荐哈,原因就是 传过来的对象和data里面定义的对象 指向的都是同一个地址,所以可以修改,如果你去定义一个简单的数据类型
// template
<view @click="add(num)"> {{num}} </view>
//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
<template>
<view class="">
<view class="box1 flexA" v-for="(item,index) in list" >
<view class="" @click="toggleStatus(item,index)">
<image v-if="item.status==true" src="/static/yes.png" mode=""></image>
<image v-else src="/static/noCur.png" mode=""></image>
</view>
<view class="" style="margin-left: 100rpx;">
<view class="flexJ" style="width: 400rpx;">
<view class="">商品名称 </view>
<view class="">{{item.name}}</view>
</view>
<view class="flexJ" style="width: 400rpx;">
<view class="">数量</view>
<view class="">{{item.num}}</view>
</view>
<view class="flexJ" style="width: 400rpx;">
<view class="">价钱</view>
<view class="">¥{{item.price}}</view>
</view>
</view>
</view>
</view>
</template>
//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,
}],
我们想呢 点击哪个按钮 就让谁切换它的状态,看上面的数据哈 每一项都有一个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 的区别
版权归原作者 同学们听懂了吗 所有, 如有侵权,请联系我们删除。