「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」。
Vue3已经出来一段时间了,相信大家都知道了Vue3做了一些优化,比如改用Proxy劫持数据,弥补了Vue2 使用defineProperty 带来的一些问题(比如无法感知到对象新增属性的改动,无法监听数组的length属性等),在开始着手迁移自己的项目前,要先了解从Vue2项目迁移到Vue3有哪些api、语法等破坏性即不兼容Vue2的地方,然后根据现有项目的依赖制定迁移计划。
破坏性改动
-
因为考虑到tree-shaking,全局API需要引入
// Vue2 this.$nextTick(() => {}) // Vue3 import { nextTick } from 'vue' setup() { ...nextTick(() => {}) }
-
Ref
v-for 中的ref绑定需定义一个数组+一个新增数组的函数,而不是直接创建一个数组,使得操作更灵活;
<div v-for="item in list" :ref="setItemRef"></div> ... data() { return { itemRefs: [] } }, methods: { setItemRef(el) { if (el) { this.itemRefs.push(el) } } },
-
.sync -> v-model
子组件需要修改prop时,Vue2是需要title.sync 修饰符+在子组件内emit('update:title', val), Vue3 可直接用v-model:title;
<input v-model="inputVal"> //Vue2 或者v-model:modelValue = "inputVal" <input :value="inputVal" @update:value="inputVal = $event"/> // Vue3
-
v-for > v-if => v-if > v-for
Vue3 中同时绑定v-for跟v-if在同一个组件上时,v-for的优先级更高,Vue3则相反;
-
v-bind 有顺序的区别了,绑定对象时属性会被靠后的覆盖
-
异步组件需要使用 defineAsyncComponent 方法去创建
-
组件事件需要写在 emits 中
类似props,接受一个对象。因为移除了 .native 修饰符,如果没有在中在emits中声明的attrs, 被挂到组件的根节点,可能会触发两次;
-
destroyted => unmounted; beforeDestory => beforeUnmount
-
mixin中的 data 合并改为浅比较
之前的data如果为嵌套的对象,那么对象中的属性也会被合并,Vue3中直接用组件中的data里面的对象去覆盖mixin data里面的同名对象。
新增
template,portal等功能。
-
template
Vue2 可通过安装插件
vue-fragment
实现React中Fragment的效果,Vue3中默认支持; -
Teleport
类似React中的Portal;
-
$attrs 新增了 class 跟 style 属性。
废除
-
Filters
可用计算属性替代;
-
:event.native 修饰符不支持了
合理使用emits替代;
-
$children 属性
可用$refs 替代。
以上是笔者比较关心或者觉得重要的改动,未介绍到的地方,请参考其他文档、文章。