vue3 的变化与优化
前端框架的通用价值(不论 vue 还是 react)
- 框架的优点
- html 不灵活,需要反复复制
- css 和 javascript 命名重复冲突
- html 和 js 强耦合
- 数据不同步
vue 的基本特征
- 大致特点
- 渐进式
- 模板语法
- 数据和视图同步
- 组件化与独立组件
vue2 老问题与 vue3 新目标
代码架构
- 所以迁移到 typescript,自动生成类型声明
- 重新设计内部模块的分层
- 为长期维护打好基础
性能优化空间
- 编译器性能一般
- 所以重写 v-dom 的算法
- 结合编译器对 v-dom 进行优化
- 优化组件实例化的开销
api 在大型项目中的可维护性
- 选项式 api 在大项目中举步维艰
- 引入对重构,复用和类型推导更友好的组合式 api
浏览器版本限制
- vue2 支持 ie9,现在 没必要了
- 现在支持最低 es2015
vue3 新特性(也基本是新优化)
数据劫持优化
- object.defineProperty 需要预先确定拦截的 key/属性
- 嵌套复杂的多层对象就需要递归调用 defineproperty,性能负担大
- vue3 用 proxy,劫持整个对象,无所谓属性
- 但也不能监听深层对象,需要显示指定递归调用
- object.defineProperty 的 get 和 set
- 处理数组是重写方法
- proxy - 对数组更友好,且能监听到数组属性
编译优化
new vue -> init() -> $mount -> compile -> render() -> vnode -> patch -> DOM
vue 的更新颗粒度是组件级别的,但很多时候我们只需要更新一个组件内的少数响应性数据,但原有的 vue2 内部依然需要循环和递归遍历 vnode 树来保证大家都更新了。但理想状态下,diff 应该能明确指向确实需要响应式变化的具体标签,其他就不用变
vue3 搞出了 block tree,能让 vnode 更新从遍历整个模板变为只和动态变化内容相关
- block tree 是一个将模板基于动态节点(有响应式变化的标签)指令切割的嵌套区块,每个区块内部的节点结构固定
- 每个区块只需要一个 array 来追踪自身包含的动态节点
运行时 diff 算法重写
- v-dom 性能优化
- 从处理后的源码看,主要是对响应式的内容打 path flag 标记,准备更新
- 而且 flag 都用位运算
slot 优化
事件监听函数的缓存优化
性能优化
源码体积
移除部分无用 api,inline,filter,
引入 tree-shaking
tree-shaking
编译阶段的静态分析就能找出没用到的模块并打标记
源码优化
monorepo 管理文件
ts 开发源码
目的是提高代码的维护性和可开发性
monorepo 代码管理
将模块拆分到不同 package 中,每个 packages 均有各自的 api,类型定义和测试
使得整体模块划分更为细致,职责更清晰,依赖关系也更明显
读起来,写起来,改起来更方便
ts 开发
类型检查
类型定义和 ide 提示
语法优化
- composition api
- options api 是一个“一个对象,包含了描述组件属性的选项”
- 逻辑复用从 mixin 变为 composition,命名冲突和来源不清晰 重写双向数据绑定
API
- 加入 fragments
- 可以写多个根节点,不像 vue2 只能写一个包住其他
- 实现方式是加虚拟节点,这些节点并不会渲染
- 支持 jsx 和 tsx
- 支持 suspense teleport 组件以及多 v-model 用法