Vue 数组和对象属性的响应式问题

Vue 数组和对象属性的响应式问题:接 https://www.cnblogs.com/twinkleG/p/15389823.html

  由于 JavaScript 的限制,响应式原理无法追踪数组和对象中属性的变化【官方文档写的是无法追踪数组和对象的变化,我觉得不严谨,对象和数组改变了还是可以追踪到的,是它们内部属性的变化无法追踪】,但是我们可以通过一些方法回避这个缺陷。

  【1】对于对象:Vue 无法检测 property 的添加和删除,由于在初始化实例时,Vue 就对 property 进行了数据劫持,设置 set 和 get 方法,所以 property 必须提前在 data 对象上存在才可以转化为响应式的.

  虽然不允许初始化实例后在 data 中添加属性,但是如果 data 最初有一个空对象,那么可以使用 Vue.set 或者 vm.$set 向这个空对象中添加响应式 property.

(1)对于添加单个属性时:

  const app = new Vue({
    el: '#app',
    data() {
      return {
        message: 'Hello Vue-API-data.',
        obj: {},
     obj_: {} } } });
  app.obj.not_reactive = 'not reactive'; // 非响应式添加
  Vue.set(app.obj, 'reactive', 'reactive property'); // 响应式

最初:

 通过 Vue.set 添加的属性,更改值后:

 直接添加属性,更改值后:

(2)对于添加多个属性时,可能会用到 Object.assign(dest, src);

  /* 添加多个属性 */
  Object.assign(app.obj_, {
    name: "James",
    age: 18
  });

但是我们看到了像以上形式直接使用 Object.assign 不是响应式的,那么我们需要这样使用:

  /* 添加多个属性 */
  app.obj_ = Object.assign({}, app.obj_, {
    name: "James",
    age: 18
  });

  【2】对于数组:数组来说比较容易,同对象一样,可以使用 Vue.set 或者 vm.$set 去给数组赋新值【或者 Array.prototype.splice】,并触发响应式更新。

  我们可以看到当你直接利用索引赋新值时,不会触发响应式更新:

  const app = new Vue({
    el: '#app',
    data() {
      return {
        message: 'Hello Vue-API-data.',
        obj: {},
        obj_: {},
        array: [1, 2, 3, 4, 5],
        array_: [6, 7, 8, 9, 10]
      }
    }
  });

而使用 Vue.set :

 

或者使用 Array.prototype.splice 方法也可以:

     【3】为何要这么设计,不允许动态向 data 添加响应式属性?

  它使得其他开发人员一看到 data 里面的属性值就知道这个实例有哪些属性了。若是可以动态添加,则一些属性还需要仔细排查。

  【4】数组一些响应式方法【共七种】:

  (1) push / pop  向尾部添加或删除元素

  (2) unshift / shift  向头部添加或删除元素  

  (3) sort / reverse  排序 、反序

  (4) splice  三种功能:添加、删除、修改

posted @ 2021-10-10 17:26  TwinkleG  Views(197)  Comments(0)    收藏  举报