前言
vue3源码地址
vue3官网地址
- vue3采用 monorepo 方式进行管理 将模块拆分到package目录中, 提高代码的可维护性和阅读性
- Vue2 后期引入RFC , 使每个版本改动可控
rfcs
Vue2不足之处
- 数据劫持: 采用Object.defineProperty, 对于层次比较深的数据 采用的是递归操作,
数组的修改用的是改写的七个方法(push, pop, unshift, shift, reverse, sort, splice)
直接修改length是无效的, 并且收集依赖dep时, 只能在数组本身收集
- 模板编译有许多不必要的cpu工作
- 组件功能多时 代码变得难以维护
- vue2是采用Facebook的Flow做类型检查(一些情况下推断有问题), 对ts支持不友好
Vue3性能优化
- 源码体积: 引入了tree-shaking减少打包体积
- 数据劫持: Vue3 劫持数据采用proxy , Vue2 劫持数据采用defineProperty(有性能问题和缺陷)
- 模板编译: 编译时 生成了Block tree, 可以对子节点的动态节点进行收集, 减少了比较, 且采用了patchFlag标记动态节点
- 语法优化: 采用compositionApi, 解决反复横跳, 优化了复用逻辑(hook)
- 增加组件: Fragment,Teleport,Suspense组件
- Vue3 采用TypeScript开发, 增强类型检测
Monorepo
- 管理项目代码的一个方式 指在一个项目仓库(repo)中管理多个模块/包(package)
- 一个仓库可维护多个模块,不用到处找仓库
- 方便版本管理和依赖管理,模块之间的引用,调用都非常方便
- 缺点:仓库体积会变大
Vue3 项目结构
* reactivity: 响应式系统
* runtime-core: 与平台无关的运行时核心 (可以创建针对特定平台的运行时 - 自定义渲染器)
* runtime-dom: 针对浏览器的运行时。包括DOM API,属性,事件处理等
* runtime-test: 用于测试
* server-renderer: 用于服务器端渲染
* compiler-core: 与平台无关的编译器核心
* compiler-dom: 针对浏览器的编译模块
* compiler-ssr: 针对服务端渲染的编译模块
* compiler-sfc: 针对单文件解析
* size-check: 用来测试代码体积
* template-explorer: 用于调试编译器输出的开发工具
* shared: 多个包之间共享的内容
* vue: 完整版本,包括运行时和编译器
浏览器编译结构图
+---------------------+
| |
| @vue/compiler-sfc |
| |
+-----+--------+------+
| |
v v
+---------------------+ +----------------------+
| | | |
+-------->| @vue/compiler-dom +--->| @vue/compiler-core |
| | | | |
+----+----+ +---------------------+ +----------------------+
| |
| vue |
| |
+----+----+ +---------------------+ +----------------------+ +-------------------+
| | | | | | |
+-------->| @vue/runtime-dom +--->| @vue/runtime-core +--->| @vue/reactivity |
| | | | | |
+---------------------+ +----------------------+ +-------------------+
下一章reactivity的源码简易实现
Vue3的响应数据简易实现-composition API(reactive, ref, toRef...)