
一、入口 initState()
- 位置
src/core/instance/state.js
- 响应式从init开始、init调用initState()初始话状态,initState中调用initData(),将data的属性,注入到vue实例,调用observe()将其转换成添加get, set方法转换响应式对象
export function initState (vm: Component) {
vm._watchers = []
...
if (opts.data) {
initData(vm)
} else {
observe(vm._data = {}, true /* asRootData */)
}
...
}
function initData (vm: Component) {
let data = vm.$options.data
...
observe(data, true )
}
二、observe(value)
- 位置
src/core/observer/index.js
- 判断如果不是对象,或者是虚拟节点, 直接返回
- 如果value含有__ob__属性, 且是Observe类型, 则已经做响应式处理过, 返回ob, 如果没有处理过, 则创建new Observer(value)
三、Observer
- 位置
src/core/observer/index.js
- 为value对象定义不可枚举的__ob__属性, 记录当前的observer对象
- 如果value是数组
-
-
- 调用
this.observeArray(value)
-
- 遍历数组中的为数组中的每一个对象创建一个 observer 实例
- 如果对象不是数组,调用walk(value),遍历对象中的每一个属性,调用defineReactive(obj, keys[i]),转换成 setter/getter
四、defineReactive
- 位置
vue/src/core/observer/index.js
- 为每一个属性创建dep对象, 如果当前属性值是对象, 递归调用observe(), getter为每一个属性收集依赖, 如果属性值是对象, 也需要为对象的每一个属性创建属性依赖, 最终返回属性值, setter设置新值, 如果新值是对象, 则调用observe,然后派发更新(发送通知),调用dep.notify()
五、收集依赖
- 在Watcher的构造器中获取
this.value = this.lazy? undefined: this.get(),调用get(), get方法中调用pushTarget(this),标记Dep.target属性(Dep.target = target)
- 在访问data中的成员时候收集依赖, defineReactive的getter收集依赖
- 把属性对应的watcher对象添加到dep的subs数组中
- 给childOb收集依赖, 目的是子对象添加和删除成员时发送通知
六、Watcher
- 触发beforeUpdate钩子函数
- 当属性的值发生变化时, 会调用dep.notify(), 会遍历subs的Watcher对象,调用update方法
- 调用
watcher.run()-->this.getter()(这个getter是this.getter = parsePath(expOrFn)也就是创建watcher时的第二个参数updateComponent)-->调用updateComponent()
- 清空上一次的依赖
- 触发actived钩子函数
- 触发updated钩子函数