[{"data":1,"prerenderedAt":535},["ShallowReactive",2],{"page-\u002Fvue\u002F源码解读\u002F目录":3},{"id":4,"title":5,"body":6,"description":12,"extension":528,"meta":529,"navigation":530,"path":531,"seo":532,"stem":533,"__hash__":534},"content\u002FVue\u002F源码解读\u002F目录.md","目录",{"type":7,"value":8,"toc":510},"minimark",[9,13,18,22,25,49,53,175,179,252,255,258,317,324,374,377,465,468,488,491,494,497,501,504,507],[10,11,12],"p",{},"这里是源码解读的开头，开通这个笔记的原因是因为想要深入理解一下Vue3的原理，能够清晰地知道现代的前端框架的具体实现，一个优秀的框架是如何开发出来的。",[14,15,17],"h2",{"id":16},"看什么","看什么？",[19,20,21],"h3",{"id":21},"track和trigger",[10,23,24],{},"核心代码的阅读需要一定的时间，推荐从依赖存储结构+track\u002Ftrigger入口 packages\u002Freactivity\u002Fsrc\u002Fdep.ts 从这里开始，订阅者的实现，在也在dep.ts中的Dep、Link。普通对象的get\u002Fset如何调用track\u002Ftrigger，packages\u002Freactivity\u002Fsrc\u002FbaseHandlers.ts。访问类型、触发类型的枚举 packages\u002Freactivity\u002Fsrc\u002Fconstants.ts。",[10,26,27,28,32,33,36,37,40,41,44,45,48],{},"阅读顺序建议：先 ",[29,30,31],"code",{},"dep.ts"," 里 ",[29,34,35],{},"targetMap"," + ",[29,38,39],{},"track","\u002F",[29,42,43],{},"trigger","，再对照 ",[29,46,47],{},"baseHandlers.ts"," 里谁在什么时机调用它们。",[19,50,52],{"id":51},"mapset的嵌套","Map\u002FSet的嵌套",[54,55,56,69],"table",{},[57,58,59],"thead",{},[60,61,62,66],"tr",{},[63,64,65],"th",{},"文件",[63,67,68],{},"内容",[70,71,72,134,162],"tbody",{},[60,73,74,80],{},[75,76,77],"td",{},[29,78,79],{},"packages\u002Freactivity\u002Fsrc\u002FcollectionHandlers.ts",[75,81,82,83,40,86,40,89,40,92,95,96,40,99,40,102,40,105,40,108,111,112,40,115,40,118,121,122,40,124,126,127,111,130,133],{},"对 ",[29,84,85],{},"Map",[29,87,88],{},"Set",[29,90,91],{},"WeakMap",[29,93,94],{},"WeakSet"," 的代理：",[29,97,98],{},"get",[29,100,101],{},"set",[29,103,104],{},"add",[29,106,107],{},"delete",[29,109,110],{},"clear","、",[29,113,114],{},"keys",[29,116,117],{},"values",[29,119,120],{},"entries","\u002F迭代器里如何 ",[29,123,39],{},[29,125,43],{},"，以及 ",[29,128,129],{},"ITERATE_KEY",[29,131,132],{},"MAP_KEY_ITERATE_KEY","。",[60,135,136,141],{},[75,137,138],{},[29,139,140],{},"packages\u002Freactivity\u002Fsrc\u002Freactive.ts",[75,142,143,146,147,150,151,154,155,158,159,133],{},[29,144,145],{},"targetTypeMap"," 把 Object\u002FArray 与 Map\u002FSet 等分成 ",[29,148,149],{},"COMMON"," \u002F ",[29,152,153],{},"COLLECTION","，决定用 ",[29,156,157],{},"baseHandlers"," 还是 ",[29,160,161],{},"collectionHandlers",[60,163,164,172],{},[75,165,166,111,169],{},[29,167,168],{},"packages\u002Freactivity\u002F__tests__\u002Fcollections\u002FMap.spec.ts",[29,170,171],{},"Set.spec.ts",[75,173,174],{},"行为与边界用例，适合对照读源码。",[19,176,178],{"id":177},"effect的作用域","Effect的作用域",[54,180,181,189],{},[57,182,183],{},[60,184,185,187],{},[63,186,65],{},[63,188,68],{},[70,190,191,218,242],{},[60,192,193,198],{},[75,194,195],{},[29,196,197],{},"packages\u002Freactivity\u002Fsrc\u002FeffectScope.ts",[75,199,200,111,203,206,207,40,210,213,214,217],{},[29,201,202],{},"EffectScope",[29,204,205],{},"activeEffectScope","、父子 scope、",[29,208,209],{},"pause",[29,211,212],{},"resume","、与 ",[29,215,216],{},"stop"," 时收集子 effect。",[60,219,220,229],{},[75,221,222,32,225,228],{},[29,223,224],{},"packages\u002Freactivity\u002Fsrc\u002Feffect.ts",[29,226,227],{},"ReactiveEffect"," 构造函数",[75,230,231,233,234,237,238,241],{},[29,232,205],{}," 存在且 ",[29,235,236],{},"active"," 时把 effect 注册进 ",[29,239,240],{},"effects"," 数组。",[60,243,244,249],{},[75,245,246],{},[29,247,248],{},"packages\u002Freactivity\u002F__tests__\u002FeffectScope.spec.ts",[75,250,251],{},"用",[19,253,254],{"id":254},"调度器",[10,256,257],{},"响应式层（单个 effect 何时跑）",[54,259,260,268],{},[57,261,262],{},[60,263,264,266],{},[63,265,65],{},[63,267,68],{},[70,269,270],{},[60,271,272,276],{},[75,273,274],{},[29,275,224],{},[75,277,278,280,281,284,285,287,288,133,291,294,295,294,298,301,302,133,305,40,308,311,312,32,314,316],{},[29,279,227],{}," 的 ",[29,282,283],{},"scheduler"," 选项；无 ",[29,286,283],{}," 时走 ",[29,289,290],{},"runIfDirty()",[29,292,293],{},"notify()"," → ",[29,296,297],{},"batch()",[29,299,300],{},"endBatch()"," 里统一 ",[29,303,304],{},"trigger()",[29,306,307],{},"startBatch",[29,309,310],{},"endBatch"," 与 ",[29,313,31],{},[29,315,43],{}," 包在一起，避免同步多次更新抖动。",[10,318,319,320,323],{},"运行时层（组件更新队列、",[29,321,322],{},"nextTick","）",[54,325,326,334],{},[57,327,328],{},[60,329,330,332],{},[63,331,65],{},[63,333,68],{},[70,335,336,354],{},[60,337,338,343],{},[75,339,340],{},[29,341,342],{},"packages\u002Fruntime-core\u002Fsrc\u002Fscheduler.ts",[75,344,345,111,348,111,351,353],{},[29,346,347],{},"queueJob",[29,349,350],{},"flushJobs",[29,352,322],{},"、组件 render effect 如何被排队（和「纯 reactivity」的 batch 是不同一层）。",[60,355,356,365],{},[75,357,358,361,362,323],{},[29,359,360],{},"packages\u002Fruntime-core\u002Fsrc\u002Frenderer.ts","（搜 ",[29,363,364],{},"effect.scheduler",[75,366,367,368,370,371,133],{},"组件级 effect 如何把 ",[29,369,283],{}," 设为 ",[29,372,373],{},"queueJob(job)",[19,375,376],{"id":376},"深度响应式转换",[54,378,379,387],{},[57,380,381],{},[60,382,383,385],{},[63,384,65],{},[63,386,68],{},[70,388,389,414,430,448],{},[60,390,391,395],{},[75,392,393],{},[29,394,140],{},[75,396,397,40,400,40,403,406,407,111,410,413],{},[29,398,399],{},"reactive",[29,401,402],{},"readonly",[29,404,405],{},"shallowReactive"," 等、",[29,408,409],{},"createReactiveObject",[29,411,412],{},"reactiveMap"," 等 WeakMap 缓存、与 handler 的选用。",[60,415,416,421],{},[75,417,418],{},[29,419,420],{},"packages\u002Freactivity\u002Fsrc\u002Fref.ts",[75,422,423,426,427,133],{},[29,424,425],{},"ref","、嵌套 ref 解包与 ",[29,428,429],{},"triggerRef",[60,431,432,437],{},[75,433,434],{},[29,435,436],{},"packages\u002Freactivity\u002Fsrc\u002FbaseHandlers.ts",[75,438,439,440,442,443,40,445,447],{},"深层代理时 ",[29,441,98],{}," 里对子对象的 ",[29,444,399],{},[29,446,402],{}," 包装。",[60,449,450,455],{},[75,451,452],{},[29,453,454],{},"packages\u002Freactivity\u002Fsrc\u002FarrayInstrumentations.ts",[75,456,457,458,111,461,464],{},"数组方法（",[29,459,460],{},"includes",[29,462,463],{},"push"," 等）的特殊 instrument，避免重复 track 或语义问题。",[19,466,467],{"id":467},"边缘情况与测试",[10,469,470,471,474,475,111,478,111,481,111,484,487],{},"优先看 ",[29,472,473],{},"packages\u002Freactivity\u002F__tests__\u002F"," 下与主题对应的 spec（例如 ",[29,476,477],{},"effect.spec.ts",[29,479,480],{},"reactive.spec.ts",[29,482,483],{},"reactiveArray.spec.ts",[29,485,486],{},"effectScope.spec.ts","、collections 目录）。这些文件往往直接对应「容易踩坑」的行为。",[14,489,490],{"id":490},"注意",[19,492,493],{"id":493},"区分编译时和运行时",[10,495,496],{},"我们需要有一个虚拟DOM，调用渲染方法将虚拟DOM渲染为真实的DOM，缺点就是虚拟DOM编写比较麻烦，专门写一个编译时可以将模板编译成虚拟DOM（构建的时候进行编译性能更高，不需要在运行的时候进行编译，并且Vue3在编译中也做了很多的优化）。",[19,498,500],{"id":499},"vue3-的模块拆分","Vue3 的模块拆分",[10,502,503],{},"Vue3的模块之间耦合度都比较低，模块可以独立使用，拆分模块很方便。通过摇树机制按需引入，可以减少用户打包之后的体积，组合式API。Vue3还可以自定义渲染器，扩展能力很强，扩展比较方便。",[14,505,506],{"id":506},"文件夹",[10,508,509],{},"![[Pasted image 20260407133505.png]]",{"title":511,"searchDepth":512,"depth":512,"links":513},"",2,[514,523,527],{"id":16,"depth":512,"text":17,"children":515},[516,518,519,520,521,522],{"id":21,"depth":517,"text":21},3,{"id":51,"depth":517,"text":52},{"id":177,"depth":517,"text":178},{"id":254,"depth":517,"text":254},{"id":376,"depth":517,"text":376},{"id":467,"depth":517,"text":467},{"id":490,"depth":512,"text":490,"children":524},[525,526],{"id":493,"depth":517,"text":493},{"id":499,"depth":517,"text":500},{"id":506,"depth":512,"text":506},"md",{},true,"\u002Fvue\u002F源码解读\u002F目录",{"description":12},"Vue\u002F源码解读\u002F目录","Woq1fZC8ZpRfdO_XKomOIwRXIZTRLf7V6v5f1Zm6B10",1791042472999]