Vue Observer
流程分析
流程一,初始化
这个操作是在initData中Observer实例初始化时通过defineReactive函数实现,同时每个属性对应一个dep实例。同时Watcher被实例化,每个组件都有相应的Watcher实例。
1 | // 在初始化属性时,初始化观察者,并且遍历属性,使其成为响应属性 |
流程二,收集依赖
当render函数运行时,getter将被触发,此时watcher收集依赖。【将wathcer添加到dep的subscribes中】
1 | // 渲染函数运行时,触发各个属性的getter |
流程三,触发更新
属性被赋值时,值变更触发依赖更新:
1 | // 属性发生变更时,触发对应属性的setter |
代码实现
Observer [观察者]
源码注释👹
Observer class that are attached to each observed object. Once attached, the observer converts target object's property keys into getter/setters that collect dependencies and dispatches updates.
解读
观察者,会为目标对象上的各个属性添加getter/setters
, 用于收集依赖,触发更新。
属性
1 | value: any; |
方法
- constructor
- walk
- observeArray
流程
1 | observe(data, true) |
Watcher [侦听器]
源码中的注释👹
A watcher parses an expression, collects dependencies, and fires callback when the expression value changes. This is used for both the $watch() api and directives.
侦听器,解析一个表达式,并且收集过程中的依赖,当表达式的值发生变化时,触发回调函数。
属性
1 | vm: Component, |
方法
- get
- cleanupDeps
- update
- run
- getAndInvoke
- evaluate
- depend
- teardown
流程
1 | new Watcher(vm, expOrFn, cb, opitons) |
Dep [依赖]
源码注释👹
A dep is an observable that can have multiple directives subscribing to it. Sub array to save which properties depend on it
解读
用于记录订阅者(Sub数组),并为每个vue实例的侦听器添加属性依赖
属性
1 | static target: ?Watcher, |
方法
- addSub
- removeSub
- depend
- notify
流程
1 | new Dep() |
scheduler [调度器]
流程
1 | watcher.update() |
关于queueWatcher
源码注释👹
Push a watcher into the watcher queue. Jobs with duplicate IDs will be skipped unless it's pushed when the queue is being flushed.
解读
将监听器放入队列尾部。重复的任务将会被跳过。
关于flushSchedulerQueue
源码注释👹
Flush both queues and run the watchers.
解读
清空队列并且运行监听器的回调函数
检测变化的注意事项
- 不能检测到对象属性的添加或删除。