vue

Vue--视图不更新解决方案

2020-10-15  本文已影响0人  某时橙

写在前面:

由于vue本身的缺陷(也可以说是js本身的缺陷),在vue中,特定的数值的改变可能并不会引起数值更新,即使在调试工具中已经显示数据更新了。

于是,你焦头烂额,先是打开调试工具,查看数据更新,然后对自己的源码一通乱改,解决无果,于是打开百度、谷歌各大搜索引擎搜索一通,最后发现,各个回答水平参差不齐,运气好,你可能10分钟解决问题,运气不好,可能就是n个10分钟。所以为了解决这样的问题,我决定写下这篇文章,帮助有困难的小伙伴解决问题。

part1.为什么视图会没有变化?

VUE的视图更新是通过拦截器实现的,但这其中并不包括对数组类型数据的下标引用,即

array[0]=8;

这种形式的数据变化不会被vue检测到。
but,vue在原生方法

Array.push()
Array.pop()
Array.shift()
Array.unshift()
Array.splice(i,n,arr)
Array.sort()
Array.reverse()

设置有拦截器,所以如果可能,请尽量用这些方法来改变数组数据而不是下标直接索引。
除此之外,在Obeject类型的对象中:

object['anyProperty']=8

是可以被vue拦截检测的。
如果想完全了解这其中的过程移步:
Vue源码系列-Vue中文社区

你可能会疑惑,为什么vue不对数组的下标索引数据设置拦截器?原因很简单设置不了。
demo:

const obj = {
  data: { name: '李华', age: null },
  set age(value) {
    console.log('通过代理设置');
    this.data.age = value;
  },
  get age() {
    console.log('通过代理获得');
    return `年龄是: ${this.data.age}`;
  }
};
obj.age = 99; //通过代理设置
console.log(obj) //{ name: '李华', age: 99 }

对象尚且可以用js原生的能力直接设置拦截器,但数组却不行,因为数组没办法设置set property,get property。所以这既是vue的缺陷,也是js的缺陷。

part2.解决方案

1.使用全局API

  <div id="app">
        <p>{{array}}</p>
        <button @click="changeData">change_array</button>
        <button @click="deleteData">delete_array</button>
    </div>
    let app = new Vue({
        el: '#app',
        data: {
            array: [0, 1, 2, 3],
        },
        methods: {
            changeData: function () {
                this.$set(this.array,0,8)
            },
            deleteData:function(){
               this.$delete(this.array,0)
            }
        }
    })

2.让VUE强制检测一次数组

    changeData: function () {
                this.array[0] = 8;
                this.array.push();
            },

所以你完全可以把这两行语句封装成一个函数

          function arrChange(array,index,newData){
                 this.array[index] = newData;
                this.array.push();
           }
//在vue使用
           changeData: function () {
                arrChange.call(this,this.array,0,8)
            },

是不是很眼熟?
删除同理,不赘述

3.使用vuex

移步:vuex官方文档
这里不推荐使用这种方法,因为相比于上面所述的方法,过于冗余。

上一篇下一篇

猜你喜欢

热点阅读