vue3相比vue2有哪些变化

文章类型:Vue

发布者:admin

发布时间:2023-03-25

vue3版本的发布,相对于vue2,有哪些变化

一底层上:

(一):更小体积

1:移除一些不常用的 API

2:引入tree-shaking,可以将无用模块“剪辑”,仅打包需要的功能模块

(二):更快编译速度

1:重写了虚拟Dom,diff算法优化

V2是全量比较,当数据改变的时候,会从头到尾的进行vDom对比,即使有些内容是固定不变的

V3 叫静态标记(PatchFlag),就是内容改变,会给一个flag,下次数据更新直接找到标记位置进行对比替换

2:hoistStatic 静态提升

V2中无论元素是否参与更新,都会重新创建。

V3 中对不参与更新的元素,只会被创建一次,渲染时候被不停的复用。避免重复创建节点,优化了运行内存占用,

将静态节点的定义,提升到父作用域,缓存起来,多个相邻的静态节点,合并起来,拿空间换时间的优化策略

3:cacheHandlers 事件监听缓存

绑定事件会被视为动态绑定,每次都会去追踪它的变化,是同一个函数,没有追踪变化,直接缓存起来复用

4:SSR优化

静态节点直接输出,绕过了vdom,动态节点,进行动态渲染

(三):更加友好

1:兼顾vue2的options API的同时还推出了composition API

2:灵活的逻辑组合与复用

3:模块可以和其他框架搭配使用

4:基于typescipt编写的,有自动的类型定义提示

(四):响应系统

V2中采用 defineProperty来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加getter和setter,实现响应式

V3采用proxy重写了响应式系统,对整个对象进行监听,不需要深度遍历,可以监听动态属性的添加,可以监听删除属性

,可以监听到数组的索引和数组length属性,

(五):更接近原生

可以自定义渲染 API

(六):更易使用

响应式 Api 暴露出来,轻松识别组件重新渲染原因

二:新特性上

(一):framents ,组件现在支持有多个根节点

<template>
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
</template>

(二):Teleport,能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置,

说白了就是可以插到任意位置,目的就是解决v2中处理嵌套组件的定位、z-index 和样式问题

<button @click="showToast" class="btn">打开 toast</button>
<!-- to 属性就是目标位置 -->
<teleport to="#teleport-target">
<div v-if="visible" class="toast-wrap">
<div class="toast-msg">我是一个 Toast 文案</div>
</div>
</teleport>

(三):composition Api

组合式api,更加容易维护我们的代码,将相同功能的变量进行一个集中式的管理

(四):createRenderer

能够构建自定义渲染器,我们能够将 vue 的开发模型扩展到其他平台

import { createRenderer } from '@vue/runtime-core'

const { render, createApp } = createRenderer({
patchProp,
insert,
remove,
createElement,
// ...
})

export { render, createApp }

三:非兼容变更

(一):Global API

1:全局 Vue API 已更改为使用应用程序实例

const app = createApp(App)

2:全局和内部 API 已经被重构为可 tree-shakable,通常于描述移除 JavaScript 上下文中的未引用代码(dead-code) 。

依赖于ES2015中的 import 和 export 语句,用来检测代码模块是否被导出、导入,且被 JavaScript 文件使用

(二):模板指令

1:组件上 v-model 用法更改,可以支持多个

2:<template v-for>和 非 v-for节点上key用法更改,必须绑定key

3: v-if 和 v-for 优先级更改,v-if优先级更高

4:v-bind="object" 现在排序敏感,绑定的顺序决定了它们如何合并

// 2.x中 id最终为red  3.x中 id为blue
<div id="red" v-bind="{ id: 'blue' }"></div>

5:v-for 中的 ref 不再注册 ref 数组,V2 中使用 ref属性时,从$refs中获取的相应属性会是一个ref数组。

V3中则将ref绑定到一个更灵活的函数上 (ele) => { …//保存ele的操作 }

<div v-for="item in list":ref="setItemRef"></div>
let itemRefs =[]constsetItemRef= el =>{ itemRefs.push(el)}

(三):组件

1:只能使用普通函数创建功能组件,

2:functional 属性在单文件组件 (SFC),

3:异步组件现在需要 defineAsyncComponent 方法来创建

(四):渲染函数

1:渲染函数API改变

2:$scopedSlots property 已删除,所有插槽都通过 $slots 作为函数暴露

3:自定义指令 API 已更改为与组件生命周期一致

4:一些转换class被重命名了:v-enter -> v-enter-from,v-leave -> v-leave-from

5:组件 watch 选项和实例方法 $watch不再支持点分隔字符串路径,用计算函数作为参数

6:在 V 2 中,应用根容器的 outerHTML 将替换为根组件模板 (如果根组件没有模板/渲染选项,则最终编译为模板)。V3. 现在使用应用程序容器的 innerHTML。

(五):其他改变

1: 生命周期destroyed-> unmounted、beforeDestroy ->beforeUnmount

2:prop default工厂函数不再有权访问 this 是上下文

4:自定义指令 API 已更改为与组件生命周期一致

5:data 始终为函数

6:来自 mixin 的 data 选项现在可简单地合并

7:attribute 强制策略已更改

8:一些过渡 class 被重命名

9:组建 watch 选项和实例方法 $watch不再支持以点分隔的字符串路径。用计算属性函数作为参数。

10:<template> 没有特殊指令的标记 (v-if/else-if/else、v-for 或 v-slot) 现在被视为普通元素,并将生成原生的 <template> 元素,而不是渲染其内部内容。在V2 中,应用根容器的 outerHTML 将替换为根组件模板 (如果根组件没有模板/渲染选项,则最终编译为模板)。V3 现在使用应用容器的 innerHTML,容器本身不再是模板的一部分

(六):移除 API

1:keyCode 支持作为 v-on 的修饰符

2:$on,$off和$once 实例方法

3:过滤filter

4:内联模板 attribute

5:$destroy 实例方法