uniapp vue2 转 vue3

将 uniapp 项目从 Vue2 迁移到 Vue3 需要进行一些必要的调整,以确保项目能够正常运行。以下是一些关键步骤和注意事项:

创建应用实例

在 Vue2 中,应用实例的创建方式如下:

复制代码
// Vue 2
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
 ...App
})
app.$mount()

在 Vue3 中,应用实例的创建方式有所不同:

复制代码
// Vue 3
import { createSSRApp } from 'vue'
import App from './App'
export function createApp() {
 const app = createSSRApp(App)
 return {
   app
 }
}

全局属性

在 Vue2 中,可以通过 Vue.prototype 来定义全局属性:

复制代码
// Vue 2
Vue.prototype.$http = () => {};

在 Vue3 中,需要使用 app.config.globalProperties

复制代码
// Vue 3
const app = createApp({});
app.config.globalProperties.$http = () => {};

插件使用

在 Vue2 中,插件的使用方式如下:

复制代码
// Vue 2
import store from "./store";
Vue.prototype.$store = store;

在 Vue3 中,插件的使用方式有所变化:

复制代码
// Vue 3
import store from "./store";
const app = createApp(App);
app.use(store);

vuex 用法

复制代码
//  Vue 2 中使用
  import Vue from 'vue'
  import Vuex from 'vuex'
  Vue.use(Vuex)
  const store = new Vuex.Store({
      state: {}
  })
  export default store
 
// Vue 3 中使用 (建议使用pinia)
  import { createStore } from 'vuex'
  const store = createStore({
      state: {}
  })
  export default store

模块导入和导出

Vue3 只支持 ES6 模块规范,因此需要将 CommonJS 模块改为 ES6 模块:

复制代码
// Vue 2
var utils = require("../../../common/util.js");
module.exports.X = X;
// Vue 3
import utils from "../../../common/util.js";
export default { X };

生命周期的适配

在 Vue3 中,组件卸载的生命周期被重新命名:

  • destroyed 修改为 unmounted

  • beforeDestroy 修改为 beforeUnmount

生命周期变更对照表:
vue2 (Options API) Vue3 (Composition API / setup) 说明
beforeCreate / created setup() 本身 直接在 setup 顶层编写
beforeDestroy onBeforeUnmount 需从 vue 引入
destroyed onUnmounted 需从 vue 引入
activated / deactivated onActivated / onDeactivated 保持缓存逻辑

事件的适配

Vue3 提供了一个 emits 选项,用于定义组件可以向其父对象发出的事件:

这里解决截图 上面的警告

复制代码
// Vue 3
export default {
 emits: ["click"],
 inheritAttrs:false,
 methods: {
   onClick() {
     this.$emit("click", "OK");
   },
 },
};

v-model 的适配

Vue3 的 v-model 语法有所变化,支持多 model:

复制代码
// Vue 3
export default {
 props: {
   modelValue: String,
 },
 methods: {
   updateValue(value) {
//将之前的 this.$emit('input') 修改为 this.$emit('update:modelValue') 
     this.$emit('update:modelValue', value);
   }
 }
};

在模板中使用:

复制代码
<ChildComponent v-model="pageTitle" />
<!-- 等同于 -->
<ChildComponent :modelValue="pageTitle" @update:modelValue="pageTitle = $event" />

插槽的适配

Vue3 不再支持 slot="xxx" 的用法,需要使用 v-slot:xxx

复制代码
<!-- Vue 2 -->
<uni-nav-bar>
 <view slot="left" class="city"></view>
</uni-nav-bar>
<!-- Vue 3 -->
<uni-nav-bar>
 <template v-slot:left>
   <view class="city"></view>
 </template>
</uni-nav-bar>

在 Vue3 中,处理 API Promise 化 调用结果的方式不同于 Vue2更多

  • Vue3 中,调用成功会进入 then 方法,调用失败会进入 catch 方法

  • Vue2 中,调用无论成功还是失败,都会进入 then 方法,返回数据的第一个参数是错误对象,第二个参数是返回数据

  • Vue 2 写法转 Vue 3 写法

复制代码
  // 在 main.js 中写入以下代码即可
  function isPromise(obj) {
    return (
      !!obj &&
      (typeof obj === "object" || typeof obj === "function") &&
      typeof obj.then === "function"
    );
  }
   
  uni.addInterceptor({
    returnValue(res) {
      if (!isPromise(res)) {
        return res;
      }
      return new Promise((resolve, reject) => {
        res.then((res) => {
          if (res[0]) {
            reject(res[0]);
          } else {
            resolve(res[1]);
          }
        });
      });
    },
  });

Vue 3 写法转 Vue 2 写法

复制代码
// 在 main.js 中写入以下代码即可
function isPromise(obj) {
  return (
    !!obj &&
    (typeof obj === "object" || typeof obj === "function") &&
    typeof obj.then === "function"
  );
}
 
uni.addInterceptor({
  returnValue(res) {
    if (!isPromise(res)) {
      return res;
    }
    const returnValue = [undefined, undefined];
    return res
      .then((res) => {
        returnValue[1] = res;
      })
      .catch((err) => {
        returnValue[0] = err;
      })
      .then(() => returnValue);
  },
});
相关推荐
Web4Browser1 小时前
Headless 浏览器自动化适合哪些任务?巡检、截图和提交动作要分级
运维·前端·自动化
用户059540174461 小时前
把前端内存泄漏排查从2小时压到5分钟,我们把它集成进了CI
前端·css
WindfallSheng2 小时前
从Vibe Coding到Spec Coding:一套可落地的AI-SDD企业级研发实战工程
javascript·vue.js
Asize2 小时前
Agent 入门:从 LLM 与 Agent 的区别到 Function Calling
javascript·人工智能
申君健24864182772022 小时前
Vapor 核心数据结构:Block原理
前端
Csvn2 小时前
工程化专题 | 改完组件保存,浏览器毫无反应,重启 dev server 又好了——气不气?
前端
我有满天星辰3 小时前
Vue 指令完全指南:从 Vue 2 到 Vue 3 的演进与实战
前端·javascript·vue.js
光影少年3 小时前
RN 渲染原理:不依赖WebView,原生控件渲染
前端·react native·react.js·前端框架
小白学过的代码3 小时前
# flv.js / mpegts.js 播不了国标摄像头(H.265 + G.711A)?纯前端 Jessibuca 无后端方案(附完整代码)
前端·javascript·h.265