vue响应式数据原理

vue2.x的响应式

劫持一个个属性

  • 实现原理:

    • 对象类型:通过Object.defineProperty()对属性的读取(getter)、修改(setter)进行拦截(数据劫持)。

    • 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。

      1
      2
      3
      4
      Object.defineProperty(data, 'count', {
      get () {},
      set () {}
      })
  • 存在问题:

    • 新增属性、删除属性, 界面不会更新。
    • 直接通过下标修改数组, 界面不会自动更新。
    • 不能监视到数组索引的值的变化。

//模拟实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
let data = {
name:'xxx',
address:'xx',
}

//创建一个监视的实例对象,用于监视data中属性的变化
const obs = new Observer(data)
console.log(obs)

//准备一个vm实例对象
let vm = {}
vm._data = data = obs

function Observer(obj){
//汇总对象中所有的属性形成一个数组
const keys = Object.keys(obj)
//遍历
keys.forEach((k)=>{
Object.defineProperty(this,k,{
get(){
return obj[k]
},
set(val){
console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)
obj[k] = val
}
})
})
}

// 解析模板,生成虚拟DOM,对比虚拟dom

Vue3.0的响应式

代理整个对象

  • 实现原理:

    • 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除、根据数组下标更改值等。

    • 通过Reflect(反射): 对源对象的属性进行操作。

    • MDN文档中描述的Proxy与Reflect:

  • 不写{}的get、set、deleteProperty也可,但是无法捕获到数据的变化

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2022-2024 CoffeeLin
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信