美文网首页vue
Vue--视图不更新解决方案

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

作者: 某时橙 | 来源:发表于2020-10-15 22:19 被阅读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官方文档
    这里不推荐使用这种方法,因为相比于上面所述的方法,过于冗余。

    相关文章

      网友评论

        本文标题:Vue--视图不更新解决方案

        本文链接:https://www.haomeiwen.com/subject/rtjrpktx.html