乐趣区

关于vue.js:Vue3Vue2实现数据响应式的区别

Vue2 实现响应式的外围:

  • 对象:通过 defineProperty 对对象的已有属性值的读取和批改进行劫持(监督 / 拦挡)
  • 数组:通过重写数组更新数组一系列更新元素的办法来实现元素批改的劫持

1、应用 observe 函数遍历 data 的每个属性


2、调用 Object.defineProperty()对每个属性做响应式解决:利用拦截器属性 get()和 set()办法做订阅 - 公布解决。

3、当对一个属性进行响应式解决的适宜,会实例化一个 Dep 实例,并将用到这个属性的组件所对应的 Watcher 实例全副寄存在 subs 数组里,当属性被批改时,告诉 watcher,调用外面的 render 函数,进行 dom 的 diff 和更新。

问题:

  • 须要遍历须要监听的每个对象的每个属性,对其增加 definePropert 办法,通过其外部的 get()和 set()办法进行数据的监听和拦挡,实现非常复杂。
  • 对象间接新增加的属性或删除已有属性,界面不会自动更新,须要应用 Vue.set()
  • 间接通过下标替换元素或更新 length,界面也不会自动更新
  • 数据的响应式解决和视图未齐全解耦

Vue3 实现响应式的外围:
通过 proxy 代理:拦挡对 data 任意属性的任意操作,包含属性值的读写,属性的增加,属性的删除等。
通过 reflect 反射,动静对被代理对象的相应属性进行特定的操作。

// 申明一个一般对象,让其变成一个 proxy 代理响应式对象
let user = {
  name: 'Liane',
  age: 18
}

// 通过 new 运算符,实例化一个 proxy 对象,new Proxy(target, handler)
// 参数 1、target-- 指标对象
// 参数 2、handler-- 处理器对象,用来监督数据,及数据操作
let proxyUser = new Proxy(user, {
  // 获取指标对象的某个属性值
  get(target, prop) {console.log('get 办法调用了')
    // 通过 Reflect 反射,对被代理对象 (指标对象) 的相应属性进行特定操作
    return Reflect.get(target, prop)
  },
  // 批改指标对象的属性值 / 为指标对象增加新的属性
  set(target, prop, value) {console.log('set 办法调用了')
    return Reflect.set(target, prop, value)
  },
  // 删除指标对象上的某个属性值
  deleteProperty(target, prop) {console.log('delete 办法调用了')
    return Reflect.deleteProperty(target, prop)
  }
})

console.log(proxyUser) //Proxy {name:"Liane",age:18}
// 通过代理对象获取指标对象中的某个属性值
console.log(proxyUser.name) //Liane
// 批改源对象的属性,代理对象的值也会批改
user.name = 'Ann'
console.log(proxyUser.name) //Ann
// 通过代理对象,批改指标对象上的属性值
proxyUser.name = 'Rose'
console.log(user.name)  //Rose
// 通过代理对象,删除指标对象上的属性值
delete proxyUser.name
console.log(user) //{age:18}
</script >

长处:

  • 在咱们动静为 data 增加属性时,不须要做任何解决,这个属性就曾经是响应式的了。(不必循环遍历 data 的每个属性,对属性都做一遍响应式解决,而是间接代理整个 data 对象)
  • 数组的任何操作也能够触发相应。
退出移动版