今天做项目的时候遇到了这样一个需求:有一个小商店,总共出售十几样商品,每个商品都有单独的编辑加减数量,有点像购物车一样。
然后我的第一想法就是用数组来遍历每一个v-model的值,然后发现好像是可行的。但是这时候问题出现了,我点击加一减一的时候,view却没有更新,
然后就去网上查了一些资料,然后才知道其中的原因,现在来给大家分享一下。
HTML代码
<div class="goods" v-for="(item,idx) in goodsList" :key="item.id">
<!-- 数量减少 -->
<div class="reduce" @click="reduce(idx)" ref="reduce" v-else><span>-</span></div>
<!-- 手动输入 -->
<input type="text" v-model="inputArr[idx]" maxlength="3" @input="onInput(idx)" @blur="onBlur(idx)">
<!-- 数量增加 -->
<div class="add" @click="add(idx)" ref="add" v-else><span>+</span></div>
</div>
JS代码
data:{
goodsList: [{
id:1,
num: 0,
price: 20,
}, {
id:2,
num: 0,
price: 30,
}, {
id:3,
num: 0,
price: 20,
}, {
id:4,
num: 0,
price: 40,
}, {
id:5,
num: 0,
price: 30,
}, {
id:6,
num: 0,
price: 120,
}, {
id:1,
num: 0,
price: 200,
}, {
id:7,
num: 0,
price: 203,
}, {
id:8,
num: 0,
price: 201,
}\],
inputArr: [0, 0, 0, 0, 0, 0, 0, 0],
},
methods: {
//减少积分
reduce: function(idx) {
this.inputArr[idx] -= 1
},
//增加积分
add: function(idx) {
this.inputArr[idx] += 1
},
// 手动输入数量
onInput: function(idx) {
// 只能输入数字
var reg = /[^\d]/g;
if (reg.test(that.inputArr[idx])) {
that.inputArr[idx] = 1;
}
},
// 失去焦点
onBlur:function(idx){
if (this.inputArr[idx] <= 0 || this.inputArr[idx] == '') {
this.inputArr[idx] = 0;
}
},
}
运行结果
这里就不上截图了,直接说结果了(当然,如果想自己操作的小伙伴可以自己试一下),结果就是不管你怎么点击加号或者减号,视图都不会改变,还是默认值0,那这是为什么呢?
这是因为vue实现双向数据绑定的机制是数据劫持,也就是在所有对象上有个Object.defineProperty()方法,通过监听set,get方法去实现,而数组没有这两个方法,所以就不会更新view;解决方案就是,需要我们主动通知vue;
解决方案:
方案1:
//减少积分
reduce: function(idx) {
vm.$set(this.inputArr, idx,this.inputArr[idx]-=1)
},
//增加积分
add: function(idx) {
vm.$set(this.inputArr, idx,this.inputArr[idx]+=1)
},
// 手动输入数量
onInput: function(idx) {
// 只能输入数字
var reg = /[^\d]/g;
if (reg.test(that.inputArr[idx])) {
that.inputArr[idx] = 1;
}
},
// 失去焦点
onBlur:function(idx){
if (this.inputArr[idx] <= 0 || this.inputArr[idx] == '') {
vm.$set(this.inputArr, idx, 0)
}
},
方案2:
//减少积分
reduce: function(idx) {
Vue.set(this.inputArr, idx,this.inputArr[idx]-=1)
},
//增加积分
add: function(idx) {
Vue.set(this.inputArr, idx,this.inputArr[idx]+=1)
},
// 手动输入数量
onInput: function(idx) {
// 只能输入数字
var reg = /[^\d]/g;
if (reg.test(that.inputArr[idx])) {
that.inputArr[idx] = 1;
}
},
// 失去焦点
onBlur:function(idx){
if (this.inputArr[idx] <= 0 || this.inputArr[idx] == '') {
Vue.set(this.inputArr, idx, 0)
}
},
方案3:
//减少积分
reduce: function(idx) {
that.inputArr.splice(idx, 1, that.inputArr[idx] -= 1);
},
//增加积分
add: function(idx) {
that.inputArr.splice(idx, 1, that.inputArr[idx] += 1);
},
// 手动输入数量
onInput: function(idx) {
// 只能输入数字
var reg = /[^\d]/g;
if (reg.test(that.inputArr[idx])) {
that.inputArr[idx] = 1;
}
},
// 失去焦点
onBlur:function(idx){
if (this.inputArr[idx] <= 0 || this.inputArr[idx] == '') {
this.inputArr.splice(idx, 1, "0");
}
},
注意:
1、 因为vue本身可以监听到数组的一些方法,例如: push(),pop(),shift(),unshift(),splice(),sort(),reverse()
2、因为input标签里的数值是字符串类型,我们编辑然后再+1的时候,它的数值可能就不是我们想要得到的那个了。例如:你输入了99,然后再点击加号,正常+=1的话是等于100,但是这个时候99为字符串类型,+1之后会变成991,所以不要忘记了在数量做加减操作时,先把字符串类型转成数字类型哦
//在加减方法前面加上这句即可
this.inputArr[idx] = Number(this.inputArr[idx])
好了,文章内容就到这里了,如果对您有帮助的话,记得点个小爱心支持一下哦,谢谢您!