持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
0.vue3的使用
<template>
<button @click="increment">
Count: {{ count }}
</button>
</template>
<script>
// Composition API 将组件属性暴露为函数,因此第一步是导入所需的函数
import { ref, computed, onMounted } from 'vue'
export default {
setup() {
// 使用 ref 函数声明了称为 count 的响应属性,对应于Vue2中的data函数
const count = ref(0)
// Vue2中需要在methods option中声明的函数,现在直接声明
function increment() {
count.value++
}
// 对应于Vue2中的mounted声明周期
onMounted(() => console.log('component mounted!'))
return {
count,
increment
}
}
}
</script>
1.vue3的设计目标是什么?做了哪些优化?
- 移除不常用的API
- 减少打包时间
- 优化diff算法
- 事件监听缓存
- SSR优化
- v3在兼顾了v2的optionsAPI的同时,还推出了compositionAPI,大大的增加了代码的逻辑组织和代码复用能力。
- 模块化的更加细致。比如package里的reactivity响应式库,如果用户想使用V3的响应式能力,可以单独拿出来使用,而不是像V2那样引入整个vue。
2.V3中的proxy
v2、3都是通过proxy来监听整个对象,但是proxy不可以监听对象深层次的变化,v3的解决方式是在getter中递归响应式。
3.compositionAPI相较于optionsAPI的优化
-
优化逻辑组织:只把相同功能的代码写在一起。
-
优化逻辑复用:在v2中,使用mixin实现功能混合,如果多个mixin混合,就会出现命名冲突和数据来源不清楚的问题。但是通过使用compositionAPI的这种形式,可以将需要复用的代码抽成一个hook,只在有需要调用的地方调用就行。
4.vue3的性能提升是在哪些方面体现的?
1.响应式系统
v2中采用Object.defineProperty()来劫持整个对象,然后深度遍历对象的所有属性,并给其每个属性都添加getter和setter,实现响应式。
v3采用proxy重写响应式系统,由于proxy可以监听整个对象,所以不需要深度遍历。
- 可以监听动态属性的增加
- 可以监听属性的删除
- 可以监听数组索引和数组length属性
2.源码体积
相比v2,v3的体积减小了很多,移除了一些不常用的API。且任何一个模块、函数(ref,computed,reactive等)都只会在被用到的时候才打包,没用到的被Tree Shaking摇晃掉。减小了打包体积。
3.编译优化
1.diff算法优化
v3与v2相比,增加了静态标记。在会发生变化的地方添加一个flag标志,下次变化时直接找这个地方就可以了。
2.静态提升
v3对不参与更新的元素做静态提升,只会被创建一次,之后在渲染时直接复用。
3.事件监听缓存
默认情况下,绑定事件的行为会被认为是动态绑定,每次都会追踪他的变化。
4.V3中为什么使用proxyAPI来代替definePropertyAPI
Object.defineProperty使用set和get来实现响应式。但是需要深度遍历对象的全部属性,给每个属性都添加setter和getter,这就性能造成了极大的挑战。
且通过Object.defineProperty实现的响应式,无法对数组进行监听,所以在vue2中新增了$set(), 以及重写了七个方法:push,pop,shift,unshift,sort,reverse,split。
proxy的监听是针对一个对象的,那么对这个对象的多有操作都会被监听到,这就可以完全代理所有属性了。proxy可以直接劫持整个对象,并返回一个新对象,可以只操作新的对象便可达到响应式的数据。
5.Tree Shaking
treeShaking是通过清除多余代码的方式,来优化打包体积的技术。
方法:
- 编译阶段利用ES6 Module判断哪些模块已经被加载。
- 判断哪些模块和变量未被使用或者引用,进而删除对应代码。
6.Virtual DOM
1.Virtual DOM的理解
从本质来说,Virtual DOM是一个JS对象,通过对象的形式表示DOM结构。
将页面结构抽象成对象结构,配合不同的渲染工具,使得跨平台成为可能。
通过事务的处理机制,将多次DOM修改结果一次性的渲染到页面上,减少了页面的回流、重绘的次数,提高了渲染性能。
2.Virtual DOM的解析过程
- 先将要插入到文档的DOM树结构进行解析,抽象成js对象,然后将js对象保存成JSON片段,通过rander函数将json片段渲染到成真实dom,最后将DOM片段插入到文本中。
- 当页面的状态发生改变时,重新生成一棵Virtual DOM树,然后新旧DOM树通过diff算法进行对比,记录差异。
- 最后将有差异的地方进行更新,更新方式如1所示
3.Virtual DOM的好处
- 保证性能下限
- 跨平台(因为DOM被抽象成js对象,又将对象保存成JSON字符串,所以可以跨平台渲染。)
4.diff算法原理
时间复杂度:最高O(n3)。
- 首先对比节点本身,判断是否为同一节点,如果不是同一节点,则删除该节点,创建新的节点进行替换。
- 若为相同节点,则处理该节点的子节点。删除无效的旧子节点,更新变化的旧子节点,创建新的子节点。
- 对于相同的子节点,采用递归进行比较。