8000 uniapp vue 3 升级之旅 · Issue #16 · xinglee23/Blogs · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

uniapp vue 3 升级之旅 #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
xinglee23 opened this issue Sep 10, 2024 · 0 comments
Open

uniapp vue 3 升级之旅 #16

xinglee23 opened this issue Sep 10, 2024 · 0 comments

Comments

@xinglee23
Copy link
Owner

背景

之前在公司做了一个 uniapp vue2 项目的一个升级的工作,在此记录一下,考虑到内部的开发成本,所以本文都是基于 js 进行是升级的。vue 2 升级 vue3 的好处显而易见,在此不多赘述,直接开启升级之旅。

框架搭建

HBuilder 不好用,所以使用的是 cli 的方式开搭建项目

vue create -p dcloudio/uni-preset-vue my-project

统一请求

原来请求有两种方式 uni.request 直接请求,以及基于 uni.request 请求的封装,目前统一成基于 uni.request 请求的封装,代码路径从 service/http.js 改成 utils/http.js

import { getCurrentPage, merger, generateId } from '@/utils/common.js';
const baseUrl = import.meta.env.VITE_APP_BASE_URL;

const DEFAULT_CONFIG = {
  baseUrl: baseUrl,
  data: {},
  header: {},
  method: 'post',
  timeout: 150000,
  dataType: 'json',
  responseType: 'text',
  ...
};

// 屏蔽的页面
const blockLoginPopList = [...];

let loading = true;
const requestInterceptor = (opt) => {
  const { url, isLoading } = opt;
  const u = DEFAULT_CONFIG.baseUrl + url;
  const m = merger(DEFAULT_CONFIG, opt);
  const token = uni.getStorageSync('token') || '';
  if (token) {
    m.header.token = token;
  }
  const configs = {
    ...m,
    url: u,
  };

  if (loading && isLoading) {
    loadingMask();
  }
  return configs;
};

const responseInterceptor = (res) => {
  const { code } = res.data;
  const pages = getCurrentPage();
  if (pages && pages.route) {
    const r = !blockLoginPopList.includes(pages.route);
    if (['200000', '200006'].includes(code)) {
      uni.removeStorageSync('token');
    }
  }
  return res.data;
};

const loadingMask = (opt = {}) => {
  const o = {
    ...opt,
    mask: true,
  };
  loading = false;
  uni.showLoading(o);
};

const request = (options) => {
  const { method, url } = options;
  const requestConfig = requestInterceptor(options);

  let requestId = generateId(method, url);
  if (!requestId) {
    return false;
  }

  return new Promise((resolve, reject) => {
    uni.request({
      ...requestConfig,
      header: {
        token: uni.getStorageSync('token') || '',
      },
      success: (res) => {
        const inter_res = responseInterceptor(res);
        if (inter_res.code == '000000') {
          resolve(inter_res);
        } else {
          console.log('request fail ', request, inter_res);
          reject(inter_res);
        }
      },
      fail: (err) => {
        console.log('request fail ', request);
        reject(err);
      },
      complete: () => {
        setTimeout(() => {
          loading = true;
        }, 1000);
      },
    });
  });
};

export { request };

请求方式

import { request } from '@/utils/http.js';

export const getData = (id) => {
  return request({
    url: `/xxxxxx/url`,
    method: 'GET',
  });
};

全局状态

vuex -> pinia (vue 官方推荐的状态管理库,更好的兼容性、更轻量化,打包完只有 1kb )
Pinia 语法有两种方式,一种是组合式,一种是选项式的;选项式的更好理解,所以这里使用的是选项式的。

import { createPinia } from 'pinia';
import { defineStore } from 'pinia';

export const useExpressStore = defineStore('myData', {
  state: () => ({
    data: {},
  }),
  getters: () => {},
  actions: {
    setData(data) {
      this.data = data;
    },
  },
});

Mixins -> hooks

Mixins 存在很多缺点,比如说命名冲突,相互之间有依赖维护很麻烦等;所以摈弃 mixins,改成官方更推荐的 hooks

 // 使用方式
 import { useUserStore } from '@/store/index';
 const userStore = useUserStore();

全局样式

全局样式统一放 style 里面

环境变量

环境变量使用 env 文件来控制,不同的 env 文件对应不同的 991D 境变量
.env.development -> 开发环境
.env.test -> 测试环境
.env.custom -> 自定义环境
.env.production -> 生产环境

// 本地开发,mode 后加不同的环境,可以拿到不同的环境变量: development、test、prod
"dev": "uni -p mp-weixin --mode development",

获取环境变量

vite 不支持 process 环境变量获取方式如下:
const baseUrl = import.meta.env.VITE_APP_BASE_URL
相关的环境变量统一 VITE_ 开头

// 相关变量统一 VITE 开头
VITE_APP_BASE_URL=https://xxx.com
VITE_APP_ENV=dev
...

升级过程遇到的问题

  • uni wx 等 not find
    • eslint.config.mjs 文件配置 { globals: uni: true, wx: true }
  • vue3 使用的是 vite ,不支持 commonJS, 所有的 require/module.export 方式都需要改成 import/export 的形式
  • 下图原因一般是组件未注册造成的
    image
  • 在uniapp中vue3报错Cannot read property ‘route‘ of undefined
    • 因为vue3没有this上下文,所以使用 uni.createSelectorQuery().in(this)时会出这个错误
import {getCurrentInstance} from 'vue'
const instance = getCurrentInstance(); // 获取组件实例 
const query = uni.createSelectorQuery().in(instance);
  • uniapp小程序的全局弹窗解决方法 (基于 vite)
// vite.config.js
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni';

export default defineConfig({
    plugins: [uni(), {
        name: 'any name', // 插件名称
        enforce: 'pre', // 插件的执行顺序, 我们需要再vite的核心插件前执行
        // vite提供的钩子, 处理每个文件的时候都会触发一次改钩子
        // code: string 为文件数据
        // id: string 为文件路径
        transform(code, id) {
            // 过滤出page文件
            if (/\.vue$/.test(id) && /\/pages\//.test(id)) {
                /**
                * 匹配开头的第一个标签 例:
                * <template>
                *  <view>
                *
                * 然后在下面添加需要的全局组件
                */
                code = code.replace(/[\s\S]+?<[\d\D]+?>/, _ => `
                    ${_}
                    <YourComponent />
                `)

                return code
            }
        },
    }],
})
  • eslint 配置不生效
    • 执行 npx eslint --debug . 命令,查看当前配置是否正确
    • 查看eslint 版本,我执行了npm init @eslint/config@latest自动升级了相关版本,然后配置 eslint.config.mjs文件(vite 所以用的 mjs 文件),配置完之后重启就生效了
    • 建议看官网文档
import globals from 'globals';
import pluginJs from '@eslint/js';
import vueParser from 'vue-eslint-parser';
import pluginVue from 'eslint-plugin-vue';

export default [
  {
    files: ['**/*.{js,mjs,cjs,vue}'],
    languageOptions: {
      sourceType: 'module',
      globals: { ...globals.browser, ...globals.node, uni: true, wx: true },
      parser: vueParser,
    },
  },
  pluginJs.configs.recommended,
  ...pluginVue.configs['flat/essential'],
  {
    rules: {
      'vue/multi-word-component-names': 'off',
      'vue/no-unused-vars': [
        'error',
        {
          ignorePattern: '^_',
        },
      ],
    },
  },
];

升级完前后对比:

vue3 包体积:

  • dev: 3.37MB 主包: 2.54MB
  • build:2.01MB 主包 1.52MB

vue2 包体积:

  • dev: 11.50MB 主包: 5.52MB
  • build:3.52MB 主包 1.99MB

参考:

uni-app官网

如何使用ARMS前端监控开始监控微信小程序_应用实时监控服务(ARMS)-阿里云帮助中心

Uni App + Vue3 引入高德小程序插件Js文件失败_plugins: [″],引入高德失败-CSDN博客

vue3引入wxcomponents中有带import字样会报错 - DCloud问答

如何解决“Error: xxx.js 已被代码依赖分析忽略,无法被其他模块引用”报错? | 微信开放社区

uni-app+vue3会遇到哪些问题 - 唯之为之 - 博客园

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant
0