第一次写这种文章,理解应该不深,望各位dalao们指点指点javascript
bb不来,纯干货java
Vue.watch(() => {
console.log("watch OK!!!");
app.querySelector('p').textContent = count.value;
});
复制代码
// 简化后
export function watch(effectOrSource, effectOrOptions,options) {
if (isFunction(effectOrOptions)) {
} else {
// 执行这里
return doWatch(effectOrSource, null, effectOrOptions)
}
}
复制代码
doWatch(source,cb,options){
// source 为fn 其余 在这里都不重要
// 1. 将source 处理成 getter
// 2. 将getter 打包成
// 3.经过effect 打包成一个订阅函数 即 runner 变量
// 3.1 ps: effect 很重要 下面列出了函数代码
// 4. 执行 scheduler (scheduler是判断flush获得的)
let scheduler = job => {
queuePostRenderEffect(job, suspense)
}
// 5.执行 queuePostRenderEffect 后 会将函数添加到队列并执行它
// 5.1 `下面列出了这个函数`
// 6.end 这个函数的事情作完了
}
// 这个函数会执行queuePostFlushCb而后将订阅函数放入(任务)队列
function queuePostRenderEffect(fn,suspense){
if (suspense !== null && !suspense.isResolved) {
// 不重要
} else {
// 执行 queuePostFlushCb
queuePostFlushCb(fn)
}
}
// 这个函数最大的功能就是 执行nextTick和添加队列
function queuePostFlushCb(cb: Function | Function[]) {
// ...
// 一些不重要的代码
// ...
// isFlushing不重要 最终会 执行 nextTick
if (!isFlushing) {
nextTick(flushJobs)
}
}
// 异步执行函数
function nextTick(fn?: () => void) {
return fn ? p.then(fn) : p
}
复制代码
effect( fn,options) {
// ...
// 一些不重要的代码
// ...
// 创造一个 effect对象 用于绑定一些属性和不容许重复绑定
const effect = createReactiveEffect(fn, options)
// ...
// 一些不重要的代码
// ...
return effect
}
// 建立订阅函数
function createReactiveEffect(fn, options) {
const effect = function effect(...args) {
// run 函数 下面贴了代码
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
}
复制代码
// 将订阅函数添加到 等待队列后,执行fn函数
// 若是fn中有 可触发的data getter 就将函数订阅到该发布者 // 这里不知道怎么说了
function run(effect: ReactiveEffect, fn: Function, args: any[]): any {
// 当 active 被中止 就不须要了订阅了 直接绑定便可
if (!effect.active) {
return fn(...args)
}
// 若是队列中不存在就表示此effect能够被订阅
if (activeReactiveEffectStack.indexOf(effect) === -1) {
cleanup(effect)
try {
// 先将 effect 添加到 等待订阅的队列
activeReactiveEffectStack.push(effect)
// 执行以后会触发getter 而后将effect订阅到队列
return fn(...args)
} finally {
// 当订阅以后就退出来
activeReactiveEffectStack.pop()
}
}
}
复制代码