内容输出来源 拉勾教育大前端高薪训练营
-
Vue的响应式是从Vue的实例
init()
方法中开始的,在init()
方法中先调用initState()
初始化Vue
实例的状态,在initState
方法中调用了initData()
,initData()
是把data
属性注入到Vue
实例上,并且调用observe(data)
将data
对象转化成响应式的对象。 -
observe
是响应式的入口, 在observe(value)
中,首先判断传入的参数value
是否是对象,如果不是对象直接返回。再判断value
对象是否有__ob__这个属性,如果有说明做过了响应式处理,则直接返回,如果没有,创建
observer对象,并且返回
observer`对象。 -
在创建
observer
对象时,给当前的value
对象定义不可枚举的__ob__
属性,记录当前的observer
对象,然后再进行数组的响应式处理和对象的响应式处理,数组的响应式处理就是拦截数组的几个特殊的方法,push
、pop
、shift
等,然后找到数组对象中的__ob__
对象中的dep
,调用dep
的notify()
方法,再遍历数组中每一个成员,对每个成员调用observer()
,如果这个成员是对象的话,也会转换成响应式对象。对象的响应式处理,就是调用walk
方法,walk
方法就是遍历对象的每一个属性,对每个属性调用defineReactive
方法 -
defineReactive
会为每一个属性创建对应的dep
对象,让dep
去收集依赖,如果当前属性的值是对象,会调用observe
。defineReactive
中最核心的方法是getter
和setter
。getter
的作用是收集依赖,收集依赖时, 为每一个属性收集依赖,如果这个属性的值是对象,那也要为子对象收集依赖,最后返回属性的值。在setter
中,先保存新值,如果新值是对象,也要调用observe
,把新设置的对象也转换成响应式的对象,然后派发更新(发送通知),调用dep.notify()
-
收集依赖时,在
watcher
对象的get
方法中调用pushTarget
,记录Dep.target
属性,访问data
中的成员的时候收集依赖,defineReactive
的getter
中收集依赖,把属性对应的watcher
对象添加到dep
的subs
数组中,给childOb
收集依赖,目的是子对象添加和删除成员时发送通知。 -
在数据发生变化的时候,会调用
dep.notify()
发送通知,dep.notify()
会调用watcher
对象的update()
方法,update()
中的调用的queueWatcher()会去判断
watcher是否被处理,如果这个
watcher对象没有的话添加到
queue队列中,并调用
flushScheduleQueue(),
flushScheduleQueue()触发
beforeUpdate钩子函数调用
watcher.run():
run()-->
get() -->getter()
-->updateComponent()
-
然后清空上一次的依赖
-
触发actived的钩子函数
-
触发updated钩子函数