Vue3 watch执行过程
Vue.watch(() => {
console.log("watch OK!!!");
app.querySelector('p').textContent = count.value;
});
调用watch
export function watch(effectOrSource, effectOrOptions,options) {
if (isFunction(effectOrOptions)) {
} else {
return doWatch(effectOrSource, null, effectOrOptions)
}
}
doWatch (代码有点长,直接说一下流程吧)
doWatch(source,cb,options){
let scheduler = job => {
queuePostRenderEffect(job, suspense)
}
}
function queuePostRenderEffect(fn,suspense){
if (suspense !== null && !suspense.isResolved) {
} else {
queuePostFlushCb(fn)
}
}
function queuePostFlushCb(cb: Function | Function[]) {
if (!isFlushing) {
nextTick(flushJobs)
}
}
function nextTick(fn?: () => void) {
return fn ? p.then(fn) : p
}
effect 函数(订阅函数)
effect( fn,options) {
const effect = createReactiveEffect(fn, options)
return effect
}
function createReactiveEffect(fn, options) {
const effect = function effect(...args) {
return run(effect as ReactiveEffect, fn, args)
}
effect.isEffect = true
effect.active = true
effect.raw = fn
effect.scheduler = options.scheduler
effect.onTrack = options.onTrack
effect.onTrigger = options.onTrigger
effect.onStop = options.onStop
effect.computed = options.computed
effect.deps = []
return effect
}
run 函数 (大概的理解,如有问题麻烦了)
function run(effect: ReactiveEffect, fn: Function, args: any[]): any {
if (!effect.active) {
return fn(...args)
}
if (activeReactiveEffectStack.indexOf(effect) === -1) {
cleanup(effect)
try {
activeReactiveEffectStack.push(effect)
return fn(...args)
} finally {
activeReactiveEffectStack.pop()
}
}
}