【vue】vue数据绑定数组,改变元素时不更新view问题

今天做项目的时候遇到了这样一个需求:有一个小商店,总共出售十几样商品,每个商品都有单独的编辑加减数量,有点像购物车一样。
然后我的第一想法就是用数组来遍历每一个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])

好了,文章内容就到这里了,如果对您有帮助的话,记得点个小爱心支持一下哦,谢谢您!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。