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);
  },
});
相关推荐
AC赳赳老秦31 分钟前
CSDN 技术社区数据采集:OpenClaw 抓取公开技术热帖,生成领域技术热点周报
java·大数据·前端·数据库·python·php·openclaw
结网的兔子40 分钟前
【前端开发】Web端迁移至 uni-app 及鸿蒙扩展方案对比
前端·uni-app·harmonyos
水瓶夜之1 小时前
.NET 中的新增功能系列文章——.NET SDK中的新增功能
前端·chrome·.net
笨笨狗吞噬者2 小时前
VS Code 内置浏览器打开网页
前端
SamChan902 小时前
WebSocket实现PDF翻译进度实时推送:Go后端+React前端的完整方案
前端·websocket·pdf·c#·react·机器翻译
甲维斯2 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·人工智能
奈斯先生Vector2 小时前
大模型 Agentic Workflow 架构解构:异构 API 调度与 Token 路由的多模态系统设计
开发语言·前端·架构·prompt·aigc·音视频
海带紫菜菠萝汤2 小时前
FFmpeg.wasm 实践:在浏览器中运行 FFmpeg 的能力边界与性能瓶颈
前端·javascript·ffmpeg·音视频·wasm
名字还没想好☜2 小时前
React 受控输入框光标跳到末尾:格式化输入时的 selection 丢失 bug 与修复
前端·javascript·react.js·bug·react·next.js
Access开发易登软件2 小时前
Access 怎么做前后端分离?用 Web API 读写 SQL Server
前端·数据库·人工智能·microsoft·excel·access