Vue3-Vue2实现数据响应式的区别

Vue2实现响应式的核心:数组

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

一、使用observe函数遍历data的每一个属性dom

image.png
二、调用Object.defineProperty()对每一个属性作响应式处理:利用拦截器属性get()和set()方法作订阅-发布处理。函数

image.png

三、当对一个属性进行响应式处理的适合,会实例化一个Dep实例,并将用到这个属性的组件所对应的Watcher实例所有存放在subs数组里,当属性被修改时,通知watcher,调用里面的render函数,进行dom的diff和更新。
image.pngspa

问题:代理

  • 须要遍历须要监听的每一个对象的每一个属性,对其添加definePropert方法,经过其内部的get()和set()方法进行数据的监听和拦截,实现很是复杂。
  • 对象直接新添加的属性或删除已有属性,界面不会自动更新,须要使用Vue.set()
  • 直接经过下标替换元素或更新length,界面也不会自动更新
  • 数据的响应式处理和视图未彻底解耦

Vue3实现响应式的核心:
经过proxy代理:拦截对data任意属性的任意操做,包括属性值的读写,属性的添加,属性的删除等。
经过reflect反射,动态对被代理对象的相应属性进行特定的操做。code

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

//经过new运算符,实例化一个proxy对象,new Proxy(target, handler)
//参数一、target--目标对象
//参数二、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对象)
  • 数组的任何操做也能够触发相应。
相关文章
相关标签/搜索