Vue源码之响应式对象

655 阅读2分钟

核心思想

响应式对象,核⼼就是利⽤ Object.defineProperty 给数据添加了 getter 和setter,⽬的就是为了在我们访问数据以及写数据的时候能⾃动执⾏⼀些逻辑:getter 做的事情是依赖收集,setter 做的事情是派发更新。

Vue会把props,data等变成响应式对象,在创建过程中,发现子属性也为对象则递归把该对象变成响应式。

入口

  1. src/core/instance/init.js
  1. src/core/instance/state.js

对于props

initProps

props 的初始化主要是遍历定义的 props 配置。遍历的过程主要做两件事情:⼀个是调⽤ defineReactive ⽅法把每个 prop 对应的值变成响应式,可以通过 vm._props.xxx 访问到定义 props 中对应的属性。另⼀个是通过 proxy把 vm._props.xxx 的访问代理到 vm.xxx 上。

对于data

initData

data 的初始化主要也是做两件事,⼀个是对定义 data 函数返回对象的遍历,通过 proxy把每⼀个值 vm._data.xxx 都代理到 vm.xxx 上;另⼀个是调⽤ observe ⽅法观测整个 data的变化,把 data变成响应式。

observe

observe⽅法的作⽤是给⾮VNode的对象类型数据添加⼀个Observer,如果已经添加过则直接返回,否则在满⾜⼀定条件下去实例化⼀个Observer对象实例。

Observer

Observer的构造函数逻辑很简单,⾸先实例化 Dep 对象,这块后面再说,接着为data对象添加__ob属性值为此类, def 的定义在src/core/util/lang.js 中:

defineReactive

defineReactive函数最开始初始化Dep对象的实例,接着拿到obj的属性描述符,然后对⼦对象递归调⽤ observe⽅法,这样就保证了⽆论 obj 的结构多复杂,它的所有⼦属性也能变成响应式的对象,这样我们访问或修改obj 中⼀个嵌套较深的属性,也能触发 getter 和 setter。最后利⽤Object.defineProperty去给 bj 的属性 key 添加 getter和 setter。

总结