《Vue.js 设计与实现》笔记
按书中章节分目录整理,一个知识点一篇,重点记录实现思路、核心代码与「为什么这样设计」。
快速导航
| 章节 | 主题 | 篇数 |
|---|---|---|
| 第 1 章 权衡的艺术 | 命令式与声明式的取舍、虚拟 DOM 与运行时/编译时 | 4 |
| 第 2 章 框架设计的核心要素 | Tree-Shaking、构建产物、特性开关、错误处理、TS 支持 | 7 |
| 第 3 章 Vue.js 3 的设计思路 | 虚拟 DOM、渲染器、组件、模板与模块协作 | 5 |
| 第 4 章 响应系统的作用与实现 | 副作用函数、依赖收集、调度、computed 与 watch | 11 |
| 第 5 章 非原始值的响应式方案 | Proxy / Reflect、普通对象 / 数组 / Set / Map 的代理 | 18 |
| 第 6 章 原始值的响应式方案 | ref、响应丢失、自动脱 ref | 3 |
| 第 7 章 渲染器的设计 | 渲染器与响应系统结合、渲染器基本概念、自定义渲染器 | 3 |
| 第 8 章 挂载与更新 | 属性设置、class、卸载、事件、子节点更新、Fragment | 11 |
| 第 9 章 简单 Diff 算法 | 同位置比较的缺陷、key 与 DOM 复用、移动/新增/删除 | 6 |
| 第 10 章 双端 Diff 算法 | 双端比较的四步命中、非理想状况、收尾处理 | 4 |
| 第 11 章 快速 Diff 算法 | 前置/后置预处理、source 数组与移动判断、最长递增子序列 | 3 |
| 第 12 章 组件的实现原理 | 渲染组件、实例与生命周期、props、setup、emit、插槽 | 8 |
| 第 13 章 异步组件与函数式组件 | 异步组件要解决的问题、defineAsyncComponent、超时/延迟/重试、函数式组件 | 6 |
| 第 14 章 内建组件和模块 | KeepAlive、Teleport、Transition | 7 |
| 第 15 章 编译器核心技术概览 | 编译器三阶段、AST 转换与插件化、代码生成 | 9 |
| 第 16 章 解析器 | 文本模式、状态机、标签/属性/文本/插值解析与实体解码 | 9 |
| 第 17 章 编译优化 | Block 与 PatchFlags、动态节点收集、静态提升、预字符串化、v-once | 11 |
| 第 18 章 同构渲染 | CSR/SSR/同构渲染、renderToString、客户端激活、跨平台处理 | 9 |
第 1 章 权衡的艺术
第 2 章 框架设计的核心要素
- 2.1 提升用户的开发体验
- 2.2 控制框架代码的体积
- 2.3 框架要做到良好的 Tree-Shaking
- 2.4 框架应该输出怎样的构建产物
- 2.5 特性开关
- 2.6 错误处理
- 2.7 良好的 TypeScript 类型支持
第 3 章 Vue.js 3 的设计思路
第 4 章 响应系统的作用与实现
- 4.1 响应式数据与副作用函数
- 4.2 响应式数据的基本实现
- 4.3 设计一个完善的响应系统
- 4.4 分支切换与 cleanup
- 4.5 嵌套的effect与effect栈
- 4.6 避免无限递归循环
- 4.7 调度执行
- 4.8 计算属性 computed 与 lazy
- 4.9 watch 的实现原理
- 4.10 立即执行的 watch 与回调执行时机
- 4.11 过期的副作用
第 5 章 非原始值的响应式方案
- 5.1 理解 Proxy 和 Reflect
- 5.2 JavaScript 对象及 Proxy 的工作原理
- 5.3 如何代理 Object
- 5.4 合理地触发响应
- 5.5 浅响应与深响应
- 5.6 只读和浅只读
- 5.7 代理数组
- 5.7.1 数组的索引与 length
- 5.7.2 遍历数组
- 5.7.3 数组的查找方法
- 5.7.4 隐式修改数组长度的原型方法
- 5.8 代理 Set 和 Map
- 5.8.1 如何代理Set和Map
- 5.8.2 建立响应联系
- 5.8.3 避免污染原始数据
- 5.8.4 处理forEach
- 5.8.5 迭代器方法
- 5.8.6 values与keys方法
第 6 章 原始值的响应式方案
第 7 章 渲染器的设计
第 8 章 挂载与更新
- 8.1 挂载子节点和元素的属性
- 8.2 HTML Attributes 与 DOM Properties
- 8.3 正确地设置元素属性
- 8.4 class的处理
- 8.5 卸载操作
- 8.6 区分vnode类型
- 8.7 事件的处理
- 8.8 事件冒泡与更新时机问题
- 8.9 更新子节点
- 8.10 文本节点和注释节点
- 8.11 Fragment
第 9 章 简单 Diff 算法
第 10 章 双端 Diff 算法
第 11 章 快速 Diff 算法
第 12 章 组件的实现原理
- 12.1 渲染组件
- 12.2 组件状态与自更新
- 12.3 组件实例与组件的生命周期
- 12.4 props与组件的被动更新
- 12.5 setup 函数的作用与实现
- 12.6 组件事件与 emit 的实现
- 12.7 插槽的工作原理与实现
- 12.8 注册生命周期
第 13 章 异步组件与函数式组件
- 13.1 异步组件要解决的问题
- 13.2.1 封装defineAsyncComponent函数
- 13.2.2 超时与 Error 组件
- 13.2.3 延迟与 Loading 组件
- 13.2.4 重试机制
- 13.3 函数式组件
第 14 章 内建组件和模块
- 14.1.1 组件的激活与失活
- 14.1.2 include 和 exclude
- 14.1.3 缓存管理
- 14.2.1 Teleport 组件要解决的问题
- 14.2.2 实现 Teleport 组件
- 14.3.1 原生 DOM 的过渡
- 14.3.2 实现 Transition 组件
第 15 章 编译器核心技术概览
- 15.1 模板 DSL 的编译器
- 15.2 parser 的实现原理与状态机
- 15.3 构造AST
- 15.4 AST 的转换与插件化架构
- 15.4.1 节点的访问
- 15.4.2 转换上下文与节点操作
- 15.4.3 进入与退出
- 15.5 将模板 AST 转为 JavaScript AST
- 15.6 代码生成
第 16 章 解析器
- 16.1 文本模式及其对解析器的影响
- 16.2 递归下降算法构造模板 AST
- 16.3 状态机的开启与停止
- 16.4 解析标签节点
- 16.5 解析属性
- 16.6.1 解析文本
- 16.6.2 解码命名字符引用
- 16.6.3 解码数字字符引用
- 16.7 解析插值与注释
第 17 章 编译优化
- 17.1.1 传统Diff算法问题
- 17.1.2 Block 与 PatchFlags
- 17.1.3 收集动态节点
- 17.1.4 渲染器的运行时支持
- 17.2.1 带有 v-if 指令的节点
- 17.2.2 带有 v-for 指令的节点
- 17.2.3 Fragment 的稳定性
- 17.3 静态提升
- 17.4 预字符串化
- 17.5 缓存内联事件处理函数
- 17.6 v-once