Observer , dep , watcher 是vue双向绑定的关键组成部分
observer
方法、类 | 作用 |
---|
toggleObserving (value: boolean) | 控制变量“shouldObserve”,间接控制调用observer时是否为对象创建__ob__ | class Observer(value:object | any[]) | 创建 {value,dep,vmCount} | observe (value: any, asRootData: ?boolean): Observer | void | 为value创建ob | defineReactive(obj: any,key: string,val?: any,customSetter?: Function,shallow?: boolean) | 将obj中的key定义为响应式 | set(target: any[] | any, key: string | number, val: any) :any | 为对象设值,如果是reactiveObj则触发通知 | del(target:any | any[], key: any) | 删除属性触发修改 |
export function toggleObserving (value: boolean) {
shouldObserve = value
}
export class Observer {
value: any;
dep: Dep;
vmCount: number;
constructor (value: any) {}
walk (obj: Object) {}
observeArray (items: Array<any>) {}
}
export function observe (value: any, asRootData: ?boolean): Observer | void {}
export function defineReactive(
obj: any,
key: string,
val?: any,
customSetter?: Function,
shallow?: boolean
) {}
export function set(target: any[] | any, key: string | number, val: any) :any {}
export function del(target:any | any[], key: any) {}
Dep
方法/类 | 作用 |
---|
class Dep | 依赖收集器,收集watcher | pushTarget | watcher 入栈 | popTarget | wacher出栈 |
let uid = 0
export default class Dep {
static target: WatcherInstance | null;
id: number;
subs: Array<WatcherInstance>;
constructor() {
this.id = uid++
this.subs = []
}
addSub(sub: WatcherInstance) {
this.subs.push(sub)
}
removeSub(sub: WatcherInstance) {
remove(this.subs, sub)
}
depend() {
if (Dep.target) {
Dep.target.addDep(this)
}
}
notify () {}
}
Dep.target = null
const targetStack = <WatcherInstance[]>[];
export function pushTarget(target: WatcherInstance | null) {}
export function popTarget() {}
Watcher
方法/类 | 作用 |
---|
class Watcher | 观察者,掌握着触发的回调 |
let uid = 0
export default class Watcher {
vm: Component;
expression: string;
cb: (value?: any, oldValue?: any) => void;
id: number;
deep: boolean;
user: boolean;
lazy: boolean;
sync: boolean;
dirty: boolean;
active: boolean;
deps: Array<Dep>;
newDeps: Array<Dep>;
depIds: SimpleSet;
newDepIds: SimpleSet;
before?: Function;
getter: () => any;
value: any;
constructor(
vm: Component,
expOrFn: string | Function,
cb: (value?: any, oldValue?: any) => void,
options?: WatcherOption | void,
isRenderWatcher?: boolean
) {
this.value = this.lazy
? undefined
: this.get()
}
get(): any {
pushTarget(this);
value = this.getter.call(vm, vm)
if (this.deep) {
traverse(value)
}
popTarget()
this.cleanupDeps()
return value
}
addDep(dep: DepInstance) {}
cleanupDeps() {}
update() {
if (this.lazy) {
this.dirty = true;
} else if (this.sync) {
this.run();
} else {
queueWatcher(this);
}
}
run() {}
evaluate() {
this.value = this.get()
this.dirty = false
}
depend() {
let i = this.deps.length
while (i--) {
this.deps[i].depend()
}
}
teardown() {
if (this.active) {
if (!this.vm._isBeingDestroyed) {
remove(this.vm._watchers, this)
}
let i = this.deps.length
while (i--) {
this.deps[i].removeSub(this)
}
this.active = false
}
}
}
traverse
方法/类 | 作用 |
---|
traverse(val: any) | 遍历对象(收集当前target),如果存在ob,则将其ob.dep.id记录,防止死循环 |
scheduler
方法/类 | 作用 |
---|
queueWatcher(watcher: WatcherInstance) | 将watcher加入队列中,下个周期开始触发watcher.run | flushSchedulerQueue () | 排序并触发watcher队列 |
let waiting = false;
let flushing = false;
let index = 0;
let has: { [key: number]: boolean } = {};
let circular: { [key: number]: number } = {}
export function queueWatcher(watcher: WatcherInstance) {}
function flushSchedulerQueue()
array
const methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
methodsToPatch.forEach(function (method: string) {
})
|