惊!VUE居然数据不能驱动视图?

Vue 不能检测到对象属性的添加或删除

1、划重点了:Vue 不能检测到对象属性的添加或删除

官网——深入响应式原理(https://cn.vuejs.org/v2/guide...)中介绍到:受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

上面的a是响应式的,所以a的改变后会自动渲染页面;
但是b是在vm实例创建之后添加的属性,所以他不是响应式的,当我们改变b的值的时候,通过DevTool看到的数据并不会改变,除非我们在DevTool中刷新数据,而且页面也不会刷新。

有三种解决方案:

var vm = new Vue{
    el: "#app",
    data:{
        obj:{
            name: "aaa"            
        }
    }
}

1、方案一:利用Vue.set(object,key,value)

Vue.set(vm.obj,"sex","man")

2、方案二:利用this.$set(this.object,key,value)

this.$set(this.obj,"sex","man")

3、方案三:利用Object.assign({},this.obj)

this.obj.sex = "man";
this.obj = Object.assign({},this.obj)

//或者下面方式
this.obj = Object.assign({},this.obj,{"sex","man"})

2、划重点了:删除vue实例的属性

注意:Vue 不允许在已经创建的实例上动态添加新的根级响应式属性(root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上。

对于上述Demo实例中通过this.$set添加的属性,通过以下方式删除即可:

//以下这种方式可以删除属性,同时会触发数据响应式的更新
this.$delete(this.mainData.test, "boolean");
//而通过delete this.mainData.test.boolean这种方法不能响应式更新视图层。

数组的问题

 changeArr() {
      // this.arr[0] = 112233;
      delete this.arr[0];
      console.log("这是修改之后的数组", this.arr);
      // $set(arr, 0, 112233);
    },
    changeObj() {
      // this.haha.content = "我是一个小和尚";
      delete this.haha.age;
      console.log("这是修改之后的对象", this.haha);
    }

删除数组或者对象也是不能被VUE监听到的。那就搬出了一个方法set。

利用vue中的set让修改内容的数组或者对象渲染到页面上。

对于数组:
this.$set(this.arr, 0, 112233);

对于对象:
this.$set(this.haha, "content", "我是一个小和尚");

对于set这个方法的解释。
this.$set(数组或者对象,修改的下标或者对象属性名,修改的值)

原理

首先,Vue.js是基于Object.defineProperty对对象实现“响应式化”,而对于数组,Vue.js提供的方法是重写push、pop、shift、unshift、splice、sort、reverse这七个数组方法。修改数组原型方法的代码可以参考observer/array.js以及observer/index.js。

参考Vue官网。

如果需要用数组下标修改数组并实现响应式数据变化,Vue.js提供了$set()及$remove()方法。

扩展部分:
当数组里的值是对象时,
当对象里还有一个对象时,
添加或者删除还会需要set吗~~~

代码

 data() {
    return {
      arr: [{ key: "name" }, { 12: "hhah" }, 2, 3, 4, 5, 6],
      haha: {
        name: {
          name: "lili"
             }
           }
    };
  },
  methods: {
    changeArr() {
      this.arr[0].key = 112233;
      console.log("这是修改之后的数组", this.arr);
    },
    changeObj() {
      this.haha.name.name = "我是一个小和尚";  
      console.log("这是修改之后的对象", this.haha); 
    }
  }

注意到了吗。我没有用$set哦~

这么看来,修改数组中的对象,和对象中的对象是不需要用set的!

posted @ 2020-09-10 15:42  打个大大西瓜  阅读(251)  评论(0编辑  收藏  举报