第一次写这种文章,理解应该不深,望各位dalao们指点指点
bb不来,纯干货
Vue3 watch执行过程
Vue.watch(() => {
console.log("watch OK!!!");
app.querySelector('p').textContent = count.value;
});
//Js中文网,一个神奇的网站
调用watch
// 简化后
export function watch(effectOrSource, effectOrOptions,options) {
if (isFunction(effectOrOptions)) {
} else {
// 执行这里
return doWatch(effectOrSource, null, effectOrOptions)
}
}
//Js中文网,一个神奇的网站
doWatch (代码有点长,直接说一下流程吧)
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
}
/*https://www.javascriptc.com Js中文资源网,一个帮助开发者成长的社区*/
effect 函数(订阅函数)
JS中文网 – 前端进阶资源教程 www.javascriptC.com
一个致力于帮助开发者用代码改变世界为使命的平台,每天都可以在这里找到技术世界的头条内容
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
}
/*https://www.javascriptc.com Js中文资源网,一个帮助开发者成长的社区*/
run 函数 (大概的理解,如有问题麻烦了)
// 将订阅函数添加到 等待队列后,执行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()
}
}
}
作者:不不才
链接:https://juejin.im/post/6844903957798584328
看完两件小事
如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:
- 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
- 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程
本文著作权归作者所有,如若转载,请注明出处
转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com