相关文档、站点
跟vue2比的优化
更快
- 虚拟 dom 重写
- 优化 slots 的生成
- 静态树提示
- 静态属性提升
- 基于 proxy 的响应式系统
更小
配合构建工具以及 tree shaking 机制,实现了内建能力的按需引入,从而实现了用户 bundle 的体积最小化。更容易维护
使用 TypeScript 开发源码,提升自身代码的可维护性。
模块拆分和设计上更加合理了。模块之间的耦合度非常低,很多模块可以独立安装使用,而不需要依赖完整的Vue.js运行时。Vue3.0 使用 monorepo 的项目管理方式,将代码托关于 packages 目录,各个模块代码职责单一,有着各自的 API 、类型定义和完善的测试用例。使得代码维护更加方便,单独引用 Vue 的响应式的功能也更加方便,可以直接引入 reactivity 模块,而不需要直接引入整个包,减少了包体积的大小,这点在 vue2.x 上是做不到的。
vue3.0 使用了 typescript 重构了整个项目,对于类型支持更加友好。
使用类型语言非常有利于代码的维护,可以在开发阶段就避免到很多不必要的错误,也可以借助 IDE 的类型推导能力帮助我们更好的识别参数类型。
性能优化
源码体积优化
- 移除一些冷门的 feature (比如 filter 、inline-template 等)
-
数据劫持优化
Object.defineProperty 的缺陷
需要提前设置监听对象的属性
- 不能监听对象属性的新增和删除
- 对数组下标变化无法监听到
- 对嵌套较深属性需要遍历进行数据劫持,对性能损耗较大。
Proxy API 优化点:
- 解决了 Object.defineProperty 的问题缺陷,由于 Proxy 劫持的是整个对象,所以能很好的监听到对象的变化。
- 对于深层次属性通过在 getter 中去递归响应式,所以只有对象在访问到才会变成响应式,而不是无脑递归,这也在一定程度上提升了性能。
- 支持更多的类型劫持。
编译优化
vue2.x vs vue3.0 首次渲染对比,可以看到 vue3.0 在渲染方面具有明显的优势,占据内存更小,渲染速度更快。
diff 算法也进行了优化。
vue2 的数据更新并触发重新渲染的粒度是组件级的,虽然 vue 能保证触发更新的组件最小化,但在单个组件内部依然需要遍历该组件的整个 vnode 树。
不过我们上面有许多的静态节点,只有一个动态节点,我们希望 text 变化时只更新动态节点的 diff ,这样可以避免很多不必要 diff 。然而,这点在 vue2 中是做不到的。因此, vue3 中重写了 diff 算法,添加了属性标记,通过编译阶段对静态模板的分析,编译生成了 block tree 。block tree 是一个将模板基于动态节点指令切割的嵌套区块,每个区块内部的节点结构是固定的,而且每个区块只需要以一个 Array 来追踪自身包含的动态节点。组合式API优化:Composition API
vue3.0 在逻辑复用方面具有强大的功能,相较于 vue2.x 的 mixins 语法更加利于维护和管理,特别是在大型项目的应用中。能更好的支持逻辑的封装和复用。新特性
组合式API
理解组合式api:https://juejin.cn/post/6890545920883032071
Composition API 的设计目标就是为了方便整理代码,让你自己安排结构,对主观能动性要求更高。本质上要把 Composition API 理解成在写正常的 JavaScript 代码。写 JavaScript 时候怎样把代码写的整洁干净,在写 Composition API 的时候遵循同样的最佳实践即可。要学会开始自己整理,一旦你自己开始整理,可以写出更高质量的代码。
ref
ref 函数接受参数并返回它包装在具有 value property 的对象中,然后可以使用该 property 访问或更改响应式变量的值。
换句话说, ref 对我们的值创建了一个响应式引用。
import {ref} from 'vue'
const counter = ref(0)
reactive
与 ref 的用法类似,也是将数据变成响应式数据。不同的是 ref 用于基本数据类型,而 reactive 用于复杂数据类型,比如对象和数组。
reactive 中传递的参数必须是 json 对象或者数组。
toRefs
toRefs() 函数可以将 reactive() 创建出来的响应式对象,转换为普通对象,只不过这个对象上的每个属性节点,都是 ref() 类型的响应式数据。
在 props 中的使用:
import { toRefs } from 'vue'
props: {
compData: {
type: Object,
default: () => {}
}
setup(props) {
const { compData } = toRefs(props)
console.log(compData.value)
}
Teleport
片段
触发组件选项
createRenderer
computed源码分析
https://www.cnblogs.com/xiaoheibanfe/p/14131508.html
v-slot
在 2.6.0 中,vue 为具名插槽和作用域插槽引入了一个新的统一语法(即 v-slot 指令)。它取代了 slot 和 slot-scope 在新版中的应用。
https://vue3js.cn/docs/zh/guide/component-slots.html#%E5%85%B7%E5%90%8D%E6%8F%92%E6%A7%BD