Vue3新变化
1."新"
在 API 特性方面:
Composition API
:可以更好的逻辑复用和代码组织,同一功能的代码不至于像以前一样太分散,虽然Vue2
中可以用minxin
来实现复用代码,但也存在问题,比如:方法或属性名会冲突、代码来源也不清楚等SFC Composition API
语法糖:Teleport
传送门:可以让子组件能够在视觉上跳出父组件(如父组件overflow:hidden
)Fragments
:支持多个根节点,Vue2
中,编写每个组件都需要一个父级标签进行包裹,而Vue3
不需要,内部会默认添加Fragments
;SFC CSS
变量:支持在<style></style>
里使用v-bind
,给CSS
绑定JS
变量(color: v-bind(str)
),且支持JS
表达式 (需要用引号包裹起来);Suspense
:可以在组件渲染之前的等待时间显示指定内容,比如loading
;v-memo
:新增指令可以缓存html
模板,比如v-for
列表不会变化的就缓存,简单说就是用内存换时间
在 框架 设计层面:
- 代码打包体积更小:许多
Vue
的API
可以被Tree-Shaking
,因为使用了es6module
,tree-shaking
依赖于es6
模块的静态结构特性; - 响应式的优化:用
Proxy
代替Object.defineProperty
,可以监听到数组下标变化,及对象新增属性,因为监听的不是对象属性,而是对象本身,还可拦截apply
、has
等方法; - 虚拟DOM的优化:保存静态节点直接复用(静态提升)、以及添加更新类型标记(
patchflag
)(动态绑定的元素)- 静态提升:静态提升就是不参与更新的静态节点,只会创建一次,在之后每次渲染的时候会不停的被复用;
- 更新类型标记:在对比
VNode
的时候,只对比带有更新类型标记的节点,大大减少了对比Vnode
时需要遍历的节点数量;还可以通过flag
的信息得知当前节点需要对比的内容类型; - 优化的效果:
Vue3
的渲染效率不再和模板大小成正比,而是与模板中的动态节点数量成正比;
Diff
算法 的优化:Diff算法
使用最长递增子序列
优化了对比流程,使得虚拟DOM
生成速度提升200%
在 兼容性 方面:
Vue3
不兼容IE11
,因为IE11
不兼容Proxy
其余
v-if
的优先级高于v-for
,不会再出现vue2
的v-for
,v-if
混用问题;vue3
中v-model
可以以v-model:xxx
的形式使用多次,而vue2
中只能使用一次;多次绑定需要使用sync
Vue3
用TS
编写,使得对外暴露的api
更容易结合TypeScript
。
2.watch 与 watchEffect
- watch作用是对传入的某个或多个值的变化进行监听;触发时会返回新值和老值;也就是说第一次不会执行,只有变化时才会重新执行
- watchEffect是传入一个立即执行函数,所以默认第一次也会执行一次;不需要传入监听内容,会自动收集函数内的数据源作为依赖,在依赖变化的时候又会重新执行该函数,如果没有依赖就不会执行;而且不会返回变化前后的新值和老值
watch加Immediate也可以立即执行
3.Fragments
Fragments
的出现,让 Vue3
一个组件可以有多个根节点(Vue2
一个组件只允许有一个根节点)
- 因为虚拟
DOM
是单根树形结构的,patch
方法在遍历的时候从根节点开始遍历,这就要求了只有一个根节点; - 而
Vue3
允许多个根节点,就是因为引入了Fragment
,这是一个抽象的节点,如果发现组件是多根的,就会创建一个Fragment
节点,将多根节点作为它的children
;
4.Teleport传送门
Teleport
是vue3
推出的新功能,也就是传送的意思,可以更改dom渲染的位置。
比如日常开发中很多子组件会用到dialog
,此时dialog
就会被嵌到一层层子组件内部,处理嵌套组件的定位、z-index
和样式都变得困难。Dialog
从用户感知的层面,应该是一个独立的组件,我们可以用<Teleport>
包裹Dialog
, 此时就建立了一个传送门,传送到任何地方:<teleport to="#footer">