让 Vue2 安稳升级为 Vue3

207 阅读3分钟

Breaking

实例创建方式

由 new Vue() => createApp() ;

2.x Global API3.x Instance API (`app`)
Vue.configapp.config
Vue.config.productionTip
removed [see below](https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed) )
Vue.config.ignoredElementsapp.config.isCustomElement ([see below](https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed))
Vue.componentapp.component
Vue.directiveapp.directive
Vue.mixinapp.mixin
Vue.useapp.use ([see below](https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed))

全局API

Vue3 中全局和内部 api 被重新构造为 tree-shakable 结构,以 ES 模块构建的命名导出方式访问全局API。涉及到的全局 API 改动如下:

  • Vue.nextTick
  • Vue.observable(替换为Vue.reactive
  • Vue.version
  • Vue.compile(仅完整版本)
  • Vue.set(仅在兼容版本中)
  • Vue.delete(仅在兼容版本中)

升级方案:
找到使用的全局API后替换为 ES 模块。例如:

Vue.nextTick()

<!-- would be shorthand for: -->

import { nextTick } from 'vue'

nextTick(() => {
  // something DOM-related
})

data 类型

Vue3 中:

1、data 在创建、使用和 minx 的时候始终为一个函数;
2、data 在接受 minx 时为浅合并;

升级方案:
1、将共享数据提取到外部对象中,并将其用作 data;
2、重写对共享数据的引用以指向新的共享对象;
3、将使用到的 minx 的 data 按照浅合并修改,必要时可以重构;

过渡class

过渡类名 v-enter 修改为 v-enter-from、过渡类名 v-leave 修改为 v-leave-from

升级方案:
.v-enter 字符串实例替换为 .v-enter-from .v-leave 字符串实例替换为 .v-leave-from 过渡组件相关属性名也需要进行字符串实例替换

模板指令

v-model:value => modelValue;

事件:change => update:modelValue;

升级方案:
1、 保留原来的 v-model 方式; 
2、 检查代码库的 .sync 使用情况,去掉了 .sync 修饰符;例如:

<ChildComponent v-bind:name.sync="name" /> 

 <!-- would be shorthand for: -->

<ChildComponent v-model:name="name"/> 

3、对于所有 v-model 不带参数的,确保 prop 和 event 名称分别更为 modelValue update:modelValue。例如:

<ChildComponent v-model="pageTitle" />

// ChildComponent.vue

export default {
  props: {
    modelValue: String // previously was `value: String`
  },
  methods: {
    changePageTitle(title) {
      this.$emit('update:modelValue', title) 
    }
  }
}

优先级

Vue3 中 v-if 优先级始终高于 v-for。

升级方案:
1、建议避免在同一个元素上同时使用这两个元素; 2、可以通过计算属性,过滤出可见元素的列表。

v-bind合并行为

Vue3 中 v-bind 的绑定顺序将影响渲染结果。

升级方案:
如果依赖于 v-bind 覆盖功能,确保 v-bind 先定义,再定义各个属性。

Render API

如果项目中使用