Vue2到Vue3迁移

文章详细介绍了如何将旧的Vue2项目迁移到Vue3,包括新建Vue3项目,逐步迁移业务代码,处理i18n从8到9的升级,更新router和vuex到最新版本。同时,文章提到了eventBus的替代方案,如mitt库的使用,以及Vuetify升级遇到的问题和建议直接创建新项目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

想想怎么做

懒得写,先放着

一步步来

  1. 新建一个vue3项目

将旧的业务代码搬进来, index.html搬到src下面。用yarn安装。运行项目成功后代码报错就置空一步步排查
(1). ## App.vue置空

<template>
  <header>
   111111111111111111111111111111
  </header>

  <main>
  </main>
</template>
<script>
export default {
  name: 'App',
  components: {
  },
  data: () => ({
  }),
  created() {
  },
  computed: {
  },
  methods: {
  },
}
</script>

(2). ## main.js置空

import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
  1. i18n从8升到9,vue3必须使用9版本(如果你有用的话)

起因:vue.use(i18n)报错
npm i -g yarn
yarn install vue-i18n@9.2.2(版本随你)
官网
localization.js(无所谓啥名字)

import { createI18n } from 'vue-i18n';
import cn from '../../lang/cn.js';
import de from '../../lang/de.js';
const messages = {
  de: de,
  cs: cs,
};
const defaultLocale = 'en';
const localeData = {
  legacy: false, // composition API
  globalInjection: true, //全局生效$t
  locale: defaultLocale, // 默认cn翻译
  messages
}
export function setupI18n (app) {
  const i18n = createI18n(localeData)
  app.use(i18n)
}

main.js

import { createApp } from 'vue'
import App from './App.vue'
import { setupI18n  } from './utils/localization'
const app = createApp(App)
// setupI18n(app)
app.use(setupI18n)
app.mount('#app')

html
(1):template中

{{ $t('login.accepting_termsOfService')  }}

(2)template的引号中

<a-input type="text" :placeholder="$t('messages.name')" />

(3)script中

import { useI18n } from "vue-i18n";
const { t } = useI18n();
console.log(t("messages.name"));


//setup中
import { useI18n } from "vue-i18n";
 setup(){
    const { t } = useI18n() // use as global scope
    return { t }
  }
 <p>{{ t('login.accepting_termsOfService') }}</p>

3. 升级router,vuex(必须)

github官网router升级
github官网vuex升级

yarn add vuex@next --save 
yarn add vue-router@next --save 
//router.js
import { createRouter as _createRouter, createWebHistory } from 'vue-router'
   export function createRouter() {
  return _createRouter({
  history: createWebHistory(),
  routes: [
    {
      // for all other paths not intercepted by any other route:
      path: '/:pathMatch(.*)*',       //改一下通配符规则
      redirect: '/',
    },
    ]})
//store.js
import { createStore as _createStore } from 'vuex'
export function createStore () {
  return _createStore({})
}
//main.js
import { createApp } from 'vue'
import App from './App.vue'
import { createStore } from './store/store'
import { createRouter } from './router'
const router = createRouter()
const store = createStore()

const app = createApp(App)

app.use(store).use(router)
app.mount('#app')



踩坑:
export function createRouter() {} 而不是export default function createRouter() {}

3. eventBus替代方案

(1):vue3中已经移除了emit, on等方法,Eventbus通讯使用的是发布订阅的设计模式,可以自己实现一个。(没检验,不推荐)

// bus.js
class Bus {
    listeners = {}
    constructor( { methods }) {
        this.listeners = {}
        Object.keys(methods).forEach(key => {
            this[key] = methods[key]
        })
    }
    $on(name, fn) {
        this.listeners[name] = this.listeners[name] || []
        this.listeners[name].push(fn)
    }
    $emit(name, ...args) {
        if (this.listeners[name]) {
            this.listeners[name].forEach(fn => fn.apply(null,args))
        }
    }
    $off(name, fn) {
        if (this.listeners[name]) {
            const index = this.listeners[name].indexOf(fn)
            if (index > -1) {
                this.listeners[name].splice(index, 1)
            }
        }
    }
}
export default Bus;

// eventBus.js
const eventBus = new Bus({
 methods: {
      liveUpdate(start, msg) {
      if (start) {
        this.$emit('startLiveUpdate',msg);
      } else {
        this.$emit('stopLiveUpdate', msg);
      }
    },
  }
})

export { eventBus };

// 页面
import {eventBus} from '@/utils/eventBus';
eventBus.$on('startLiveUpdate', (message) => {
      console.log("我是直接监听的",message);
    });

eventBus.$emit('startLiveUpdate', "我是emit发送的");

eventBus.liveUpdate(true, "我是方法发送的")

(2): 使用mitt代替

// eventBus.js
import mitt from 'mitt';

export const eventBus = mitt()

export const EventBus = {
  resetAllData() {
    eventBus.emit('resetAllData');
  }}

// 页面
import { EventBus, eventBus }  from '@/utils/eventBus';

// 开启监听
eventBus.on('annotationClicked', () => {
   this.curComp = 'app-annotationen';
});

// 调用EventBus方法
EventBus.liveUpdate(this.liveUpdateActive);

4. vuetify从2升到3

升级生个屁,一堆坑

npm create vuetify
新建一个vue3+vuetify3项目,然后从头再来
<think>我们正在处理一个关于Vue2迁移Vue3的问题。根据用户需求,需要提供详细步骤、最佳实践、兼容性信息和代码示例。参考引用内容:引用[1]提供了Vue2Vue3迁移步骤、代码示例和总结表格,包括核心差异、代码调整和迁移注意事项。引用[2]提供了uniapp从Vue2迁移Vue3的流程,特别提到了slot语法的变化。根据这些信息,我们将组织一个详细的迁移指南。注意:用户要求使用中文回答,并按照系统级指令处理数学公式(虽然本问题可能不涉及数学公式,但需注意格式要求)。回答结构:1.迁移准备2.核心差异概述3.详细迁移步骤(包括代码示例)4.迁移注意事项5.总结表格(对比Vue2Vue3)6.迁移工具推荐最后,生成相关问题。由于引用中已经包含部分代码示例和注意事项,我们将整合这些内容,并补充一些常见的迁移点(如组合式API、生命周期等)。</think>### Vue 2 迁移Vue 3 详细指南 #### **一、迁移准备** 1. **环境检查** - 升级 Node.js 至 v16+(Vue 3 最低要求) - 更新 CLI:`npm install -g @vue/cli` - 创建迁移分支:`git checkout -b vue3-migration` 2. **依赖评估** ```bash vue add vue-next # 官方迁移助手 npx vue-demi # 检测第三方库兼容性 ``` 重点检查: - `vue-router` → v4.x - `vuex` → 建议迁移到 [Pinia](https://pinia.vuejs.org/) - UI库(如Element-UI需升级为[Element Plus](https://element-plus.org/)) --- #### **二、核心代码迁移** ##### 1. **响应式系统重构** ```javascript // Vue 2 (Options API) data() { return { count: 0 } } // Vue 3 (Composition API) import { ref } from &#39;vue&#39; setup() { const count = ref(0) return { count } } ``` ##### 2. **状态管理迁移到 Pinia** ```javascript // store.js (Vue 3 + Pinia) import { defineStore } from &#39;pinia&#39; export const useCounterStore = defineStore(&#39;counter&#39;, { state: () => ({ count: 0 }), actions: { increment() { this.count++ } } }) ``` ##### 3. **生命周期钩子调整** | Vue 2 | Vue 3 | |---------------|-------------------| | `beforeCreate`| `setup()` | | `created` | `setup()` | | `mounted` | `onMounted()` | | `destroyed` | `onUnmounted()` | --- #### **三、模板语法变更** ##### 1. **Slot 语法统一** ```html <!-- Vue 2 (已废弃) --> <uni-nav-bar> <view slot="left">...</view> </uni-nav-bar> <!-- Vue 3 (标准语法) --> <uni-nav-bar> <template v-slot:left> <!-- 或简写 #left --> <view>...</view> </template> </uni-nav-bar> ``` ##### 2. **v-model 升级** ```html <!-- Vue 2 --> <ChildComponent v-model="value" /> <!-- Vue 3 (支持多v-model) --> <ChildComponent v-model:title="pageTitle" v-model:content="pageContent" /> ``` ##### 3. **事件监听简写** ```html <!-- Vue 2 --> <button v-on:click="handleClick">Click</button> <!-- Vue 3 --> <button @click="handleClick">Click</button> ``` --- #### **四、渐进式迁移策略** 1. **混合模式过渡** 在 Vue 2 项目中安装 `@vue/composition-api`: ```bash npm install @vue/composition-api ``` ```javascript // main.js (Vue 2) import VueCompositionAPI from &#39;@vue/composition-api&#39; Vue.use(VueCompositionAPI) ``` 2. **组件级迁移优先级** ```mermaid graph LR A[工具类组件] --> B[业务简单组件] B --> C[核心业务组件] C --> D[路由/状态管理] ``` 3. **TypeScript 配置** ```json // tsconfig.json { "compilerOptions": { "types": ["vite/client", "pinia"], "strict": true } } ``` --- #### **五、关键注意事项** 1. **`this` 上下文变更** Vue 3 的 `setup()` 中 `this` 为 `undefined`,访问组件实例需用: ```javascript import { getCurrentInstance } from &#39;vue&#39; const instance = getCurrentInstance() ``` 2. **全局 API 改造** ```javascript // Vue 2 Vue.prototype.$http = axios // Vue 3 const app = createApp(App) app.config.globalProperties.$http = axios ``` 3. **异步组件语法** ```javascript // Vue 2 const Foo = () => import(&#39;./Foo.vue&#39;) // Vue 3 import { defineAsyncComponent } from &#39;vue&#39; const Foo = defineAsyncComponent(() => import(&#39;./Foo.vue&#39;)) ``` --- #### **六、迁移总结表格** | 迁移内容 | Vue 2 | Vue 3 | 关键调整 | |------------------|---------------------|-----------------------|------------------------------| | **响应式数据** | `data()` 对象 | `reactive()`/`ref()` | 必须显式声明响应式 | | **状态管理** | Vuex | Pinia | API 更简洁,支持组合式 | | **路由** | Vue Router 3.x | Vue Router 4.x | `createRouter` 替代构造函数 | | **生命周期** | `created`/`mounted` | `onCreated`/`onMounted` | 钩子名改为 `onXXX` 形式 | | **模板指令** | `v-on:click` | `@click` | 统一使用简写语法 | | **Slot 作用域** | `slot-scope` | `v-slot` | 必须使用 `<template>` 包裹 | > 官方迁移工具推荐: > ```bash > npx @vue/cli-service-global migrate # 自动检测不兼容点 > ``` [^1][^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值