Vue2 迁移到 Vue3 的完全构建方法


 vue-cli 构建版本使用官方的迁移构建版本进行迁移。

01

准备工作

1. 废弃的 slot 语法

<template slot="header">
   <h1>Here might be a page title</h1>  
</template>

替换为 name 或者 v-slot

<header>
    <slot name="header"></slot>
</header>

 <template v-slot:header> 
   <h1>Here might be a page title</h1>
 </template>

v-slot 只能添加在 <template> 上

缩写

<template #header>
    <h1>Here might be a page title</h1>
</template>

2. 废弃的 slot-scope 语法

 <template slot="default" slot-scope="slotProps">
    {{ slotProps.user}} 
 </template>

替换为

<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
</current-user>

解构传值

<current-user v-slot="{ user }">
  {{ user.firstName }}
</current-user>

02

安装

1. 升级工具

vue-cli:通过 vue upgrade 升级到最新的 @vue/cli-service。

2. package.json

"dependencies": {
-  "vue": "^2.6.12",
+  "vue": "^3.1.0",
+  "@vue/compat": "^3.1.0"
   ...
},
"devDependencies": {
-  "vue-template-compiler": "^2.6.12"
+  "@vue/compiler-sfc": "^3.1.0"
}

3. 构建设置

// vue.config.js

module.exports = {
  chainWebpack: config => {
    config.resolve.alias.set('vue', '@vue/compat')

    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => {
        return {
          ...options,
          compilerOptions: {
            compatConfig: {
              MODE: 2
            }
          }
        }
      })
  }}

4. Typescript

添加一个 *.d.ts 文件

declare module 'vue' {
  import { CompatVue } from '@vue/runtime-dom'
  const Vue: CompatVue
  export default Vue
  export * from '@vue/runtime-dom'
}

5. 编译错误或警告

例如 filters 相关的编写,进行修复

6. 命令行和浏览器控制台的警告

优先修复自己代码中的警告,再处理依赖如 vue-router 的警告

7.升级 <transition> 类名

在运行时没有警告

8.更新应用入口,全局API 移动到实例下

import { createApp } from 'vue'
const app = createApp({})
2.x 全局 API3.x 实例 API (app)
Vue.configapp.config
Vue.config.productionTip移除
Vue.config.ignoredElementsapp.config.compilerOptions.isCustomElement
Vue.componentapp.component
Vue.directiveapp.directive
Vue.mixinapp.mixin
Vue.useapp.use
Vue.prototypeapp.config.globalProperties
Vue.extend移除
API 迁移

9.升级vuex

 "vuex": "^4.0.0",
app.use(store) //使用方法

store/index.js修改为

import { createStore as _createStore } from 'vuex'
export function createStore () {
  return _createStore({
    state: {}
  })
}

10.升级 vue-router

"vue-router": "^4.0.0",
import { createApp, configureCompat } from 'vue'

import { createRouter as _createRouter, createWebHistory } from 'vue-router'

11.compatConfig 选项

行为冲突——例如渲染函数 API,或函数式组件 vs. 异步组件的改变。

一个组件可以使用 compatConfig 选项,并支持与全局 configureCompat 方法相同的选项。

对单个组件选择性启用 Vue 3 的行为

 compatConfig: {
    MODE: 3, // 只为这个组件选择性启用 Vue 3 行为
    FEATURE_ID_A: true // 也可以在组件级别开启某些特性
 }

12.移除迁移构建版本

移除@vue/compat,只使用Vue3

03

兼容性配置

1. 全局配置

import { configureCompat } from 'vue'

// 所有 Vue 3 的默认行为,并开启某些兼容性特性

configureCompat({
  MODE: 3,
  FEATURE_ID_A: true,
  FEATURE_ID_B: true
})

2.基于单个组件的配置

export default {
  compatConfig: {
    MODE: 3, // 只为这个组件选择性启用 Vue 3 行为
    FEATURE_ID_A: true // 也可以在组件级别开启某些特性
  }
  // ...
}

3. 针对编译器的配置

l以 COMPILER_ 开头的特性是针对编译器

04

完全兼容语法

ID描述
GLOBAL_MOUNTnew Vue() -> createApp
GLOBAL_EXTENDVue.extend 被移除 (使用 defineComponent 或 extends 选项)
GLOBAL_PROTOTYPEVue.prototype -> app.config.globalProperties
GLOBAL_OBSERVABLEVue.observable 被移除 (使用 reactive)
CONFIG_KEY_CODESconfig.keyCodes 被移除
CONFIG_WHITESPACE在 Vue 3 中空格默认为 “condense”
INSTANCE_EVENT_EMITTERvm.$on、vm.$off、vm.$once 被移除
INSTANCE_EVENT_HOOKS实例不再抛出 hook:x 事件
INSTANCE_CHILDRENvm.$children 被移除
INSTANCE_LISTENERSvm.$listeners 被移除
INSTANCE_SCOPED_SLOTSvm.$scopedSlots 被移除;vm.$slots 现在暴露函数
INSTANCE_ATTRS_CLASS_STYLE$attrs 现在包含了 class 和 style
OPTIONS_DATA_FNdata 在所有情况下都必须是一个函数
OPTIONS_DATA_MERGE来自 mixin 或扩展的 data 现在都是浅合并
OPTIONS_BEFORE_DESTROYbeforeDestroy -> beforeUnmount
OPTIONS_DESTROYEDdestroyed -> unmounted
WATCH_ARRAY对于一个数组的操作,侦听无法被触发了,除非使用了深度侦听
V_FOR_REFv-for 内的 ref 不再注册 ref 数组
V_ON_KEYCODE_MODIFIERv-on 不再支持 keyCode 修饰符
CUSTOM_DIR自定义指令钩子命名变化
ATTR_FALSE_VALUEattribute 的绑定值为布尔值 false 时不再将其移除
ATTR_ENUMERATED_COERCION不再特殊处理枚举类型 attribute
TRANSITION_GROUP_ROOT不再默认渲染一个根元素
COMPONENT_ASYNC异步组件 API 改变 (现在需要 defineAsyncComponent)
COMPONENT_FUNCTIONAL函数式组件 API 改变 (现在必须只是一个普通函数)
COMPONENT_V_MODEL组件的 v-model 修改
RENDER_FUNCTION渲染函数 API 更改
FILTERS过滤器被移除 (该选项只会影响运行时的过滤器 API)
COMPILER_IS_ON_ELEMENTis 的使用现在被严格限制在上
COMPILER_V_BIND_SYNCv-bind.sync 被替换为带参数的 v-model
COMPILER_V_BIND_PROPv-bind.prop 修饰符被移除
COMPILER_V_BIND_OBJECT_ORDERv-bind=”object” 现在是顺序敏感的
COMPILER_V_ON_NATIVEv-on.native 修饰符被移除
COMPILER_V_FOR_REFv-for 中的 ref (编译器支持))
COMPILER_NATIVE_TEMPLATE没有特殊指令的
COMPILER_FILTERS过滤器 (编译器支持)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注