Module Index
模块索引
Vue 3.6
围绕运行时、组件更新和响应式演进,拆解 Vue 3.6 的核心实现链路。
Alien Signals
新的响应式模型、依赖传播和 effect 设计。
Alien Signals 的诞生背景与价值
理解 Monorepo:多包管理的概念
环境构建:从零到一建立 Monorepo 工作流
极致性能:使用 ESBuild 极速构建
响应式原理:数据与副作用的关联机制
底层结构:链表
前文我们梳理了响应式的工作模式。要继续深入,我们需要探究 Vue 3 在实现卓越性能时所依赖的关键基石:对核心数据结构的选择与约束。
链式追踪:优化多依赖监听的解决方案
职责分离:解耦依赖收集与更新派发
执行边界:Effect 上下文管理与边界
调度策略:Scheduler 优化更新性能
重复收集陷阱:Effect 触发的性能危机
复用机制:基于链表节点的依赖去重
在前文的分析中,我们发现响应式系统存在依赖重复收集导致的指数级性能爆炸问题。问题的核心在于:每次 effect 重新执行时,它都“忘记”了自己之前收集的依赖,从而创建冗余的 Link 节点。
倍增触发:多依赖场景下的通知风暴解析
迭代复用:高效解决多依赖重复收集
前文我们发现,在多依赖场景下,即使引入了节点复用机制,由于 依赖读取顺序的变化 或 状态管理不当,依然会导致冗余 Link 节点的创建。问题的核心在于:复用检查缺乏迭代能力。
依赖有效性:响应式系统的“依赖清理”挑战
优雅清理:过期依赖的防残留解决方案
内存优化:对象池复用 Link 节点的实践
防重入锁:阻止无限循环依赖的机制
模块设计:reactivity 核心理念与架构
基础骨架:WeakMap 实现三层依赖存储
进阶掌握:reactivity 的高级特性与陷阱
模块解耦:reactivity 架构的逻辑拆分
computed的设计和实现:双重角色的响应式节点
computed:缺陷修复与惰性求值实现
前文我们虽然初步实现了 computed 的双重角色,但在实际应用中,它暴露了两个核心缺陷:冗余执行 和 不必要的更新传播 ,导致其性能远低于官方实现。
watch:核心实现
watch 允许在 响应式数据发生变化时,执行特定的副作用(Side Effect)。核心思想是基于 effect 的 调度机制( scheduler)。
watch:副作用清理
响应式系统中的数组长度联动
在之前的处理中,虽然对对象的处理已经完善,但数组与对象不同
Vue3 响应式工具:toRef、toRefs、unRef、proxyRef
在使用 Vue 3 的 reactive 时,我们经常习惯性的使用 ES6 解构赋值。
响应式探索之旅完结
看到这里的话, 关于 vue3 响应式的核心实现就拆解完了
runtime
平台运行时、DOM 操作和运行时能力封装。
runtime-core
组件实例、渲染器、调度器和更新链路。
h 函数 -> Vue 的虚拟节点创建机制
shapeFlag -> Vue 的类型标识系统
在上一章中,我们已经成功实现了渲染功能,但其中使用了一个硬编码的 shapeFlag: 9。那么这个神秘的数字到底代表什么含义呢?让我们深入探讨一下 Vue 中的类型标识系统。
Renderer -> 挂载与卸载机制
在之前的学习过程中,我们一直使用 Vue 官方提供的 createRenderer 和 render 函数。现在,让我们深入了解其内部实现原理,创建属于自己的渲染器。
Renderer 更新 -> Diff 算法基础
在上一章中,我们实现了渲染器的挂载和卸载功能。现在,让我们继续完善渲染器的更新机制,当数据发生变化时,渲染器需要高效地对比新旧虚拟节点,并将变化应用到真实 DOM 上。
Renderer 更新 -> 双端 Diff
在上一章中,我们实现了 patchChildren 的大部分逻辑,但当新旧节点的子节点都是数组时,我们留下了一个 TODO。这种场景需要使用 diff 算法来高效地对比和更新子节点。本章将实现双端 diff 算法,这是 Vue 渲染器中最核心的优化之一。
Renderer 更新 -> 乱序 Diff
在上一章中,我们实现了双端 diff 算法,能够高效处理头部和尾部的节点变化。但在实际应用中,还会遇到更复杂的场景——节点的顺序发生了变化,或者中间插入、删除了节点。这种情况下,双端对比无法完全处理,需要更智能的乱序 diff 算法。
Renderer 更新 -> 最长递增子序列优化
在上一章中,我们实现了乱序 diff 算法,通过倒序插入的方式调整节点顺序。但这种做法存在一个性能问题——即使某些节点本身的相对顺序是正确的,也会被移动。实际上, DOM 移动操作是相对昂贵的,我们应该尽可能减少不必要的移动。这就是最长递增子序列算法发挥作用的地方。
Renderer 更新 -> 最长递增子序列应用
在上一章中,我们深入理解了最长递增子序列算法的原理和反向追溯技术。现在,是时候将这个强大的算法应用到 Vue 的 diff 过程中了。通过这一优化,我们能够显著减少 DOM 移动操作,提升列表更新的性能。
Renderer 更新 -> 文本节点的处理与优化
在之前的章节中,我们一直通过虚拟 DOM 创建元素节点并渲染到页面中。然而,Vue 不仅支持元素节点,还支持文本节点的独立渲染。本章将深入探讨文本节点的实现原理,以及如何通过虚拟节点标准化来简化开发体验。
createApp -> Vue 应用的初始化与挂载机制
在前面的章节中,我们实现了 render 函数来渲染虚拟节点。然而,Vue 的实际使用中更常见的是 createApp API。本章将深入 createApp 的实现原理,理解它如何封装渲染逻辑,并提供更友好的应用级 API。
组件挂载机制 -> 从创建到响应式更新
在上一章中,我们实现了 createApp API,建立了应用的初始化和挂载机制。然而,当我们尝试挂载一个组件时,会发现组件并没有真正渲染到页面上。这是因为我们还缺少组件挂载的核心逻辑。
组件属性传递 -> Props 与 Attrs 的设计与实现
在上一章中,我们实现了组件的挂载机制和响应式更新。然而,一个完整的组件系统离不开属性传递的支持。组件需要通过 props 接收外部数据,同时也需要处理未声明的 attributes。
组件实例代理 -> PublicInstanceProxy 的设计与实现
在上一章中,我们实现了 Props 与 Attrs 的分离和初始化。然而,在 render 函数中使用 this.msg 时,会发现是无法访问的。
Setup 渲染函数返回 -> Render Function 的设计与实现
在前面的章节中,我们已经实现了组件实例代理系统和属性访问拦截。在 Vue 中,除了通过 render 选项提供渲染函数外,setup 函数也可以直接返回一个渲染函数。
组件异步更新 -> Scheduler 与 nextTick 的设计与实现
在上一章中,我们实现了 Setup 返回渲染函数的能力。然而,在响应式数据多次变更时,每次变更都会触发一次组件更新,这会带来不必要的性能开销。
组件 Props 更新 -> 变更检测与更新渲染的实现
在之前的章节中,我们已经实现了组件的挂载机制。当父组件传递给子组件的 Props 发生变化时,子组件需要进行相应的更新渲染。本节将详细分析 Props 更新的完整流程。
组件事件机制 -> emit 方法的实现与组件通信
在之前的章节中,我们实现了通过父组件的 Props 传递,在更新的同时通知子组件更新。除了这种方式之外,子组件也可以通过触发事件来通知父组件,这正是 Vue 中经典的"子传父"通信模式。
组件插槽机制 -> 插槽系统与组件通信的实现
在之前的章节中,我们已经实现了组件的基本功能和 Props 传递机制。除了通过 Props 传递数据之外,Vue 还提供了强大的 插槽(Slots) 机制,允许父组件向子组件传递模板内容。
组件实例 -> getCurrentInstance 的实现
在开发过程中,有时我们需要访问组件实例本身,比如获取组件的属性、上下文或者其他内部状态。Vue 提供了 getCurrentInstance API,允许我们在 setup 函数或生命周期钩子中获取当前组件的实例。
组件生命周期 -> life cycle
在之前的章节中,我们已经实现了组件的挂载和更新机制。Vue 提供了一套完整的 生命周期系统,允许开发者在组件的不同阶段执行特定的逻辑。生命周期钩子主要分为三个阶段:挂载、更新和卸载。
获取组件实例 -> ref expose
Vue 3.2
从早期响应式系统入手,建立依赖收集和派发更新的基础模型。
Reactivity
reactive、effect、依赖收集和派发更新。
vue 响应式实现(1)
vue 响应式实现(2)
vue 响应式实现(3)
vue 响应式实现(4)
vue 响应式实现(5)
vue 响应式实现(6)
vue 指令
vue 其他组件
有点不知道怎么分类了, 先都放在这儿吧
vue 响应式(1)
vue 响应式(2)
vue setup
vue 插槽
vue 模版
vue 中的模版到最终也是会通过模版编译器编译为渲染函数的形式
vue 虚拟 dom