anchors
题外
watcher定义后会立即执行一次getter(不是cb)
this.value = this.lazy ? undefined : this.get();
defineReactive为在模型上的每个属性, 创建dep. 谁get那个属性就把target watcher添加到dep.subs里去.
render watcher
执行一次get后, 让不再引用的的属性的dep取消订阅自己.
定义computedwatcher
computedwatcher定义流程
- vm实例上定义
_computedWatchers
- - 创建watcher(传入选项
{ lazy: true }
), 创建watcher 时不调用get - 非组件实例getter将通过defineProperty挂在vm上, 组件的defineComputed, extend构造函数的时候就执行了, computed的get被挂到了vm.prototypes上进行复用
- computed watcher的get在render vnode的时候通过get属性触发.
- 先调用
watcher.evaluate
, 调用定义的computed.xx.getter, 让相关属性的dep添加这个computed watcher - 再调用
watcher.depend
, 让相关属性的dep添加render watcher
- watcher在内部依赖的属性更新时触发, watcher在调用get后会触发
render watcher
的的get执行.
- 先调用
v2.5.17
中的值不变不重新渲染,也只是昙花一现
|
|
|
|
|
|
- Watcher computed部分
|
|
computedwatcher更新流程
- setter触发update, 不加入队列,
this.dirty = true;
- 把
render watcher
加入队列,render watcher
生成vnode时再去调用vm.xx的getter =>computed watcher
的get - 重新收集
computed watcher
依赖, 更新视图12345678910111213141516171819202122232425Watcher.prototype.update = function update () {/* istanbul ignore else */if (this.lazy) {this.dirty = true;} else if (this.sync) {this.run();} else {queueWatcher(this);}};// 调用vm.xx的getter, dirty=true执行evaluatefunction computedGetter () {var watcher = this._computedWatchers && this._computedWatchers[key];if (watcher) {if (watcher.dirty) {watcher.evaluate();}if (Dep.target) {watcher.depend();}return watcher.value}}
|
|
userwatcher
watcher创建
watcher可以是数组
|
|
watcher四个options
|
|
- deep watch
|
|
- immediate 创建watch后执行一次cb
|
|
- sync watcher setter检测到变化后, 在当前tick中同步执行watcher的回调函数。
|
|