vue3新特性
# vue3 新特性
# 生命周期
选项式 API | Hook inside setup |
---|---|
beforeCreate | Not needed |
created | Not needed |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
activated | onActivated |
deactivated | onDeactivated |
# 组合式 API (Composition API)
优点:
更好的逻辑复用与代码组织,暴露给模板的 property 来源十分清晰,因为它们都是被组合逻辑函数返回的值。
不存在命名空间冲突,可以通过解构任意命名
不再需要仅为逻辑复用而创建组件实例
仅依赖它的参数和 Vue 全局导出的 API,而不是依赖其微妙的 this 上下文
参考:https://segmentfault.com/a/1190000023016699 (opens new window)
对比 vue2 的混入:
优点:mixin 可以根据逻辑关注点进行组织代码
缺点:
- 它们容易发生冲突,最终可能导致属性名称冲突。
- 不清楚混合元素如何作用,渲染上下文中暴露的 property 来源不清晰。例如在阅读一个运用了多个 mixin 的模板时,很难看出某个 property 是从哪一个 mixin 中注入的。
- 混合后的组件属性不方便在其他组件中重用。
# Proxy 和 Object.defineProperty 的对比
Proxy 是直接代理对象;而 Object.defineProperty 只能劫持对象的属性,
Proxy 能监听对象的新增和删除操作;Object.defineProperty 不能监听对象的新增和删除操作,通过 Vue.set()和 Vue.delete 来实现响应式的。
Proxy 可以直接监听数组的变化;Object.defineProperty 本身是有监控数组下标变化的能力的,只是在 Vue 的实现中,从性能/体验的性价比考虑
Proxy 支持 13 种拦截操作,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的。
Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的;而 Object.defineProperty 只能遍历对象属性直接修改;
Proxy 兼容性差;Object.defineProperty 兼容性好,支持 IE9,
Proxy 有性能问题但是有新标准性能红利,从长远来看,JS 引擎会继续优化 Proxy
# Tree-Shaking 的支持
Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination
Tree shaking 是基于 ES6 模板语法(import 与 exports),主要是借助 ES6 模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入和输出的变量
Tree shaking 无非就是做了两件事:
编译阶段利用 ES6 Module 判断哪些模块已经加载
判断那些模块和变量未被使用或者引用,进而删除对应代码
Tree-Shaking 原理:https://juejin.cn/post/6844903544756109319 (opens new window)
# Teleport 任意传送门
Teleport 是一种能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置的技术
适用场景:像 modals,toast 等这样的元素,很多情况下,我们将它完全的和我们的 Vue 应用的 DOM 完全剥离,管理起来反而会方便容易很多
# 虚拟 DOM 的优化
https://www.pianshen.com/article/16291732261/ (opens new window)
# diff 算法的优化
- 静态标记
vue2 对比是进行全量的比较:在 Vue2.0 当中,当数据发生变化,它就会新生成一个 DOM 树,并和之前的 DOM 树进行比较,找到不同的节点然后更新。但这比较的过程是全量的比较
Vue3.0 对于不参与更新的元素,做静态标记并提示,只会被创建一次,在渲染时直接复用
- 静态提升
Vue3 中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用,这样就免去了重复的创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化了运行时候的内存占用
- 对比过程
去除相同前置和后置元素
vue3 diff 对比过程:
(1) 头和头比:先进行头和头比,发现不同就结束循环
(2) 尾和尾比:再进行尾和尾比,发现不同就结束循环
(3) 基于最长递增子序列(贪心+二分查找)进行移动/添加/删除
使用最长递增子序列可以最大程度的减少 DOM 的移动,达到最少的 DOM 操作
为什么最长递增子序列就可以保证移动次数最少呢?
因为在位置数组中递增就能保证在旧数组中的相对位置的有序性,从而不需要移动,因此递增子序列的最长可以保证移动次数的最少
时间复杂度:贪心算法的时间复杂度是 O(n),二分查找的时间复杂度是 O(logn),总的时间复杂度 O(nlogn)
# TypeScript 支持
# 其它
- 片段
在 2.x 中,由于不支持多根节点组件
在 3.x 中,组件可以包含多个根节点
去除了过滤器,建议用计算属性代替
修改了 v-if 和 v-for 的优先级,vue3 中 v-if 优先级高
# vue3 更小更快
# 更快
Virtual DOM 完全重写,mounting & patching 提速 100% ;
更多编译时(compile-time)提醒以减少 runtime 开销;
基于 Proxy 观察者机制以满足全语言覆盖及更好的性能;
放弃 Object.defineProperty ,使用更快的原生 Proxy ;
组件实例初始化速度提高 100% ;
提速一倍/内存使用降低一半。
# 更小
Tree-shaking 更友好;
新的 core runtime: ~10kb gzipped
# 更易维护
Flow -> TypeScript
Decoupled Packages(解耦包)
编译器重写
# 更易于原生
自定义 Renderer API
# vue3 性能提升
# 1.编译阶段
diff 算法优化
静态提升
事件监听缓存
SSR 优化
# 2.源码体积
相比 Vue2,Vue3 整体体积变小了,除了移出一些不常用的 API,再重要的是 Tree shanking
任何一个函数,如 ref、reavtived、computed 等,仅仅在用到的时候才打包,没用到的模块都被摇掉,打包的整体体积变小
# 3.响应式系统
vue2 中采用 defineProperty 来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加 getter 和 setter,实现响应式
vue3 采用 proxy 重写了响应式系统,因为 proxy 可以对整个对象进行监听,所以不需要深度遍历