vue 的响应式

63 阅读1分钟

vue3 的响应式

利用 ES6 的 proxy 对对象进行代理,拦截对象中任意属性的变化,并通过 Reflect 反射对被代理对象的属性进行操作。

相比于 vue2 的响应式,可以动态监听到属性的变化、新增与删除,监听数组的变化,解决 vue2 不支持 Map、Set、WeakMap 和 WeakSet等缺陷。

new Proxy(data, {
  // 拦截读取属性值
  get (target, prop) {
      return Reflect.get(target, prop)
  },
  // 拦截设置属性值或添加新属性
  set (target, prop, value) {
      return Reflect.set(target, prop, value)
  },
  // 拦截删除属性
  deleteProperty (target, prop) {
      return Reflect.deleteProperty(target, prop)
  }
})

在实际的运用主要是使用 reactive 和 ref 以函数调用的方式对要展示的数据进行处理,生成响应式数据。

reactive()

接收对象类型数据的参数传入并返回响应式的对象

let man = reactive({
    name: '张三',
    age: 18,
    sex: '男'
})

ref()

接收简单类型或对象类型的数据传入并返回一个响应式的对象,在传入对象类型的时候其实内部也是使用 reactive 进行处理。

在模板可以直接使用,但是在程序中需要 .value 使用

let num = ref(18)
console.log(num.value)

vue2 的响应式

采用数据劫持结合发布者-订阅者模式的方式,使用 Object.defineProperty 劫持对象,对数据进行深度遍历所有属性,给每个属性添加 getter 和 setter 去进行 读/写 对应的属性,在数据变动时发布消息给订阅者,触发相应的监听回调。。

let person = {
  age: 18
}
let name = '张三'
Object.defineProperty(person, 'name', {
  // 读取 person 的 name 属性时,get 函数就会被调用
  get() {
    return name
  },
  // 修改 name 属性时,set 函数就被调用,收到修改的值并替换
  set(value) {
    name = value
  }
})