今天看了vue3.x的迁移指南,对内容进行一个记录
先来看一下新增了哪些内容
异步组件(vue3.x新增)
vue3.x
- 由于函数式组件被定义为纯函数,因此异步组件的定义需要通过将其包装在新的
defineAsyncComponent
助手方法中来显式地定义 component
选项现在被重命名为loader
,loader
函数不再接收resolve
和reject
参数,且必须返回promise
片段(vue3.x新增)
vue3.x
组件可以有多个根节点
看完新增的内容,再看看哪些地方做了修改
v-for
vue2.x
v-for
指令可以绑定数组的数据来渲染列表
vue3.x
从单个绑定获取多个ref
,ref
会通过迭代的key
被设置(新特性)
自定义元素交互
vue2.x
通过Vue.config.ignoredElements
配置自定义元素白名单
vue3.x
在模板编译期间执行指示编译器将<plastic-button>
视为自定义元素
- 如果使用生成步骤:将
isCustomElement
传递给 Vue模板编译器,如果使用vue-loader
,则应通过 vue-loader 的compilerOptions
选项传递 - 如果使用动态模板编译,通过
app.config.isCustomElement
传递
自定义内置元素的方法是向内置元素添加is
属性
v-is
要使用注册名称来渲染组件,其值应为 JavaScript 字符串文本
<tr v-is="'blog-post-row'"></tr>
Data选项
vue2.x
可以自定义data选项是object
或function
vue3.x
data选项只接受返回object
的function
全局API
vue2.x
有许多全局API和配置,会全局改变vue的行为
vue3.x
调用createApp
返回一个应用实例
import {createApp} from 'vue'
const app = createApp({})
config.productionTip
移除
config.ignoredElements
替换为 config.isCustomElement
下表为2.x与3.x的对比
2.x 全局 API | 3.x 实例 API (app) |
---|---|
Vue.config | app.config |
Vue.config.productionTip | 已移除 |
Vue.config.ignoredElements | app.config.isCustomElement |
Vue.component | app.component |
Vue.directive | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.use |
全局 API Treeshaking
vue2.x
Vue.nextTick()
是一个全局的 API 直接暴露在单个 Vue 对象上,回调的this
上下文自动绑定到当前实例
webpack
支持tree-shaking,但Vue 2.x 的全局 API 比如 nextTick 无法被 TreeShake,所以就算没有用到这些 API,它们还是会被打包到你的生产版本的代码包里
vue3.x
全局和内部API进行了重构,支持使用tree-shaking
需要注意的是:
当使用全局 API 时,需要主动将其导入到目标文件中
import { nextTick } from 'vue';
nextTick(() => {
// 和 DOM 有关的一些操作
});
如果直接调用Vue.nextTick()
,会导致报错:undefined is not a function
key attribute
vue2.x
建议在v-if
/v-else
/v-else-if
的分支中使用key
vue3.x
vue会自动生成唯一的key
按键修饰符
vue2.x
- 支持keyCodes作为修改
v-on
的方法 - 可以通过全局
config.keyCodes
vue3.x
- 不再支持使用数字 (即键码) 作为
v-on
修饰符,建议使用kebab-cased大小写名称 - 不再支持
config.keyCodes
在 prop 的默认函数中访问this
vue3.x
生成 prop 默认值的工厂函数不再能访问 this
渲染函数API
vue2.x
- render函数参数
render
函数自动接收h
函数作为参数 - render函数签名更改
render
函数自动接收诸如h
之类的参数
vue3.x
- render函数参数
h
是全局引入的,而不是作为参数自动传递 - render函数签名更改
render
函数不再接收任何参数,将主要用于setup()
内部,可以访问作用域中声明的响应式状态和函数以及传递给setup()
的参数
slot统一
vue2.x
在内容节点上定义slot data property
vue3.x
- 插槽被定义为当前节点的子对象
- 当需要以编程方式引用作用域slot时,被统一到
$slot
选项中
过渡类名更改
vue3.x
过渡类名 v-enter
修改为 v-enter-from
、过渡类名v-leave
修改为v-leave-from
<transition>
组件相关属性名也发生了变化:
leave-class
已经被重命名为leave-from-class
(在渲染函数或 JSX 中可以写为:leaveFromClass
)
enter-class
已经被重命名为enter-from-class
(在渲染函数或 JSX 中可以写为:enterFromClass
)
v-model
vue2.x
- 使用
v-model
指令必须使用value
的prop
; - 如果出于不同的目的使用其他的
prop
,需要使用v-bind.sync
vue3.x
- 如果要改变绑定的属性名,而不是更改组件内绑定的选项,只需要给 v-model 传递一个参数就可以了;
- 可以自定义多个v-model;
- 支持自定义修饰符
v-if与v-for的优先级比较
vue2.x
在同一个元素上同时使用v-if
和v-for
,v-for
会优先使用;
vue3.x
v-if
总是优先于v-for
生效
v-bind合并行为
vue2.x
如果一个元素同时定义了v-bind="object"
和一个相同的单独的property
,那么这个单独的 property
总是会覆盖object
中的绑定
vue3.x
如果一个元素同时定义了v-bind="object"
和一个相同的单独的property
,那么声明绑定的顺序决定了它们如何合并
函数式组件
vue2.x
- 作为性能优化
- 返回多个根节点
vue3.x
- 通过函数创建组件
所有的函数式组件都是用普通函数创建的,不需要定义{function:true}
组件选项 - 单文件组件
function
attribute 在<template>
中移除
listeners
现在作为$attrs
的一部分传递,可以删除
最后,再来看一下vue3.x废弃了哪些内容吧
$children(vue3.x已移除)
vue2.x
可以使用this.$children
直接访问当前实例的子组件
vue3.x
$children
已移除,如需访问子组件,建议使用$refs
事件API(vue3.x已移除)
$on
,$off
,$once
实例方法已被移除
vue2.x
vue实例可用于触发通过事件触发API强制附加发处理程序已创建全局事件监听器
vue3.x
移除了$on
,$off
,$once
方法,但仍可用$emit
触发由父组件以声明方式附加的事件处理程序
过滤器(vue3.x已移除)
vue2.x
可以使用过滤器来处理通用文本格式
vue3.x
过滤器已删除,可以用方法调用或计算属性替换过滤器
内联模块Attribute(vue3.x已移除)
vue2.x
Vue 为子组件提供了inline-template
attribute,以便将其内部内容用作模板,而不是将其作为分发内容
vue3.x
不再支持此功能,所有模板写在HTML页面中