说说我对 Vue 数据响应式的理解

101 阅读1分钟

1. 什么是 Vue 数据响应式

当数据改变时,UI 做出响应。 当修改 Vue 实例中的 data 属性时,UI页面中的 data 会做出响应,Vue 是通过 Object.defineProperty 来实现数据响应的。

const vm = new Vue ({data:myData})

其中 options.data

  • 会被 Vue 监听
  • 会被 Vue 实例代理
  • 每次对 data 的读写都会被 Vue 监控
  • Vue 会在 data 变化时更新 UI

2. Vue 如何实现数据响应式

2.1 通过 getter 和 setter 修改对象属性实现数据响应

在 Vue 中,用于设置 data 新增 key 的 API 为Vue.setvm.$set,如下列代码所示:

//修改姓名
let obj3 = {
  姓: "翠",
  名: "花",
  age: 18,
  get 姓名() {
    return this.姓 + this.名;
  },
  set 姓名(xxx) {
    //xxx是未来传的值,比如 obj3.王二狗
    this.姓 = xxx[0];
    this.名 = xxx.substring(1);
  }
};
obj3.姓名 = "王二狗";
console.log(`姓名:${obj3.姓}${obj3.名}`); // 姓 王, 名 二狗

2.2 定义了的对象通过Object.defineProperty(obj, 'n', {value: 4})添加属性

let data2 = {};
data2._n = 0;
Object.defineProperty(data2, "n", {
  get() {
    return this._n;
  },
  set(value) {
    if (value < 0) return;
    this._n = value;
  }
});
console.log(data2.n) // 0
data2.n=-1
console.log(data2.n) // 0,当 n = -1 < 0 , data 的属性 n 不变
data2.n=1
console.log(data2.n) // 1
  1. 给数组添加元素
  • 通过Vue.set(this.array, 3, 'd')实现数据响应或通过this.array.push('d')实现
new Vue({
  data: {
    array: ["a", "b", "c"]
  },
  template: `
    <div>
      {{array}}
      <button @click="setD">set d</button>
    </div>
  `,
  methods: {
    setD() {
      Vue.set(this.array, 3, 'd'); // 可以实现添加 d 元素
      // 如果写成 this.array[3] = "d"  ,请问,页面中会显示 'd' 吗?不会
      // 也可用 this.array.push('d')
    }
  }
}).$mount("#app");

数组变异方式 Vue 提供了7个,分别是

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse() 以上7个 API 都自动添加监听和代理并更新 UI,但用 set 就不会自动添加,且 set 之后 再用 this.array[n] += 1不会触发 UI 更新。