工具使用:
- Pinia
Vue 3 官方推荐的状态管理库,比 Vuex 更轻量 ,支持模块化, 结合 persistedstate 插件可以持久化存储数据。- uView-plus
专为 UniApp 设计,支持 App、小程序、H5。- UnoCSS
更轻量,比 TailwindCSS 性能更好,适合 UniApp。- API 请求(luch-request)
一、创建uniapp项目
注意:
- Vue3/Vite版要求 node 版本 18+、20+
- 如命令行创建失败,请直接访问 gitee 下载模板
更多的注意安装流程和注意事项可以参考官网:uni-app官网
通过 vue-cli
脚手架
创建uni-app
项目npx degit dcloudio/uni-preset-vue#vite-ts uni-vite-vant
二、编译和运行
1. 安装依赖 yarn install
2. 运行项目 yarn run dev:h5
三、配置pinia并实现持久化
Pinia官方文档:Pinia | The intuitive store for Vue.js
Persistedstate插件文档:Pinia Plugin Persistedstate
1、 安装pinia和持久化插件
使用 CLI搭建的项目安装pinia需要注意
4.14 之前
:执行 yarn add pinia@2.0.36
或 npm install pinia@2.0.36
安装,要固定版本
4.14 之后
:执行 yarn add pinia
或 npm install pinia
安装,可不指定版本
# 我们这里执行
yarn add pinia@2.0.36
# 或者使用 npm
npm install pinia@2.0.36
安装持久化插件pinia-plugin-persistedstate
npm i pinia-plugin-persistedstate
yarn add pinia-plugin-persistedstate
2、封装pinia
为减少main.ts代码冗余,这里进行封装pinia创建和持久化
(1)创建index.ts文件(路径src/stores/index.ts)

(2)完成初始化
// src/store/index
import { createPinia } from "pinia" //引入pinia
const pinia = createPinia() //创建pinia实例
export default pinia //导出pinia用于main.js注册
(3)引入并初始化pinia
//main.js
import { createSSRApp } from 'vue';
import pinia from '@/stores'; //引入
import App from './App.vue';
export function createApp() {
const app = createSSRApp(App);
app.use(pinia); //将 Pinia 挂载到全局实例
return {
app,
};
}
(4)定义store
创建store文件夹用于存放,新建user文件

将persist 选项设置为
true时则整个
整个 store 现在将使用 默认的持久性设置进行保存。
import { defineStore } from 'pinia';
// 你可以任意命名 `defineStore()` 的返回值,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。
// (比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useUserStore = defineStore('user', {
state: () => ({
count: 0,
name: 'Eduardo',
}),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
increment() {
this.count++;
},
},
// persist: true,
});
四、安装uview-plus
# 安装sass
yarn add sass@1.56.0 -D
# 或
npm i sass@1.56.0 -D
# 安装sass-loader,注意需要版本10,否则可能会导致vue与sass的兼容问题而报错
yarn add sass-loader@10 -D
# 或
npm i sass-loader@10 -D
# 安装uview
yarn add uview-plus
//
npm i uview-plus
# dayjs
yarn add dayjs
......
# clipboard
yarn add clipboard
......
在项目
src
目录中的main.js
中,引入并使用uview-plus的JS库
import { createSSRApp } from 'vue';
import pinia from '@/stores'; //引入
import App from './App.vue';
import uviewPlus from 'uview-plus';
export function createApp() {
const app = createSSRApp(App);
app.use(pinia); //将 Pinia 挂载到全局实例
app.use(uviewPlus);
return {
app,
};
}
# 引入uview-plus的全局SCSS主题文件
在项目根目录的uni.scss中引入此文件。
/* uni.scss */
@import 'uview-plus/theme.scss';
# 引入uview-plus基础样式
在App.vue中首行 的位置引入,注意给style标签加入lang="scss"属性
<style lang="scss">
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
@import "uview-plus/index.scss";
</style>
# 配置easycom组件模式
此配置需要在项目
src
目录的pages.json
中进行。
// pages.json
{
"easycom": {
"autoscan": true,
// 注意一定要放在custom里,否则无效,https://ask.dcloud.net.cn/question/131175
"custom": {
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
}
},
// 此为本身已有的内容
"pages": [
// ......
]
}
**注:**在配置完后,可以发现在mian.ts中引入uview-plus时会提示ts报错:无法找到模块"uview-plus"的声明文件。
可以在src文件中创建一个types文件夹专门用来存放ts类型声明文件,在文件中新建uview.d.ts文件写入下方声明代码即可:
declare module "uview-plus"
五、安装UnoCSS
这里可以在vscode应用市场中搜索Unocss
yarn add -D unocss
# 或者npm
npm install -D unocss
配置vite.config.ts
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
// https://vitejs.dev/config/
export default defineConfig(async () => {
/**
* 为兼容 @dcloudio/vite-plugin-uni 采用 CJS ,而 UnoCSS 只支持 ESM
* @see https://github.com/dcloudio/uni-app/issues/4815
*/
const Unocss = await import('unocss/vite').then((i) => i.default);
return {
plugins: [uni(), Unocss()],
};
});
创建UnoCSS配置文件
// uno.config.ts
import { defineConfig } from 'unocss'
export default defineConfig({
// ...UnoCSS options
})
六、luch-request请求封装
// 安装
// yarn
yarn add luch-request
// npm
npm install luch-request
在src目录下创建api/request.ts分装请求
import Request from 'luch-request';
const http = new Request({
baseURL: '', //设置请求的base url
timeout: 30000, //超时时长30秒,
header: {
'Content-Type': 'multipart/form-data;application/json;charset=UTF-8;',
},
});
//请求拦截器
http.interceptors.request.use(
(config) => {
// 可使用async await 做异步操作
const token = uni.getStorageSync('token');
if (token) {
// config.header.common['Authorization'] = 'Bearer ' + token;
}
if (config.method === 'POST') {
config.data = JSON.stringify(config.data) as unknown as Record<
string,
any
>;
}
return config;
},
(error) => {
return Promise.resolve(error);
}
);
// 响应拦截器
http.interceptors.response.use(
(response) => {
console.log(response);
return formatData(response.data);
},
(error) => {
//未登录时清空缓存跳转
if (error.statusCode == 401) {
uni.clearStorageSync();
uni.switchTab({
url: '/pages/index/index.vue',
});
}
const { errMsg } = error;
console.log(errMsg, '我才是error');
uni.showToast({
title: errMsg,
duration: 2000,
});
return Promise.resolve(error);
}
);
function formatData(data: any) {
switch (Number(data.code)) {
case 200:
return Promise.resolve(data);
// ....執行其他報錯代碼
default:
return Promise.reject(data);
}
}
export default http;
创建 api/index.ts (根据自己项目自定义文件名)
import request from './request';
export function customApi(data: Record<string, any>) {
// get请求 可以拼接url或者传入数据对象 二选一
return request.get('/list', { params: data });
}
export function toLogin(data: any) {
return request.post('/auth/login', data);
}
// 页面使用
import { customApi } from '@/api';
customApi({})
七、其他配置
(1)插件和组件自动导入
// 安装
yarn add -D unplugin-vue-components unplugin-auto-import
npm install -D unplugin-vue-components unplugin-auto-import
在
vite.config.ts
中进行如下配置:
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
export default defineConfig(async () => {
......
return {
plugins: [
AutoImport({
imports: ['vue', 'uni-app', 'vue-router'],
dts: true,
vueTemplate: true,
}),
/**
* unplugin-vue-components 按需引入组件
* 注意:需注册至 uni 之前,否则不会生效
*/
Components({
dirs: ['src/components'], // 自动导入的目录
extensions: ['vue'],
}),
......
],
};
});
插件 | 作用 |
---|---|
unplugin-vue-components | 自动导入 Vue 组件 ,无需手动 import |
unplugin-auto-import | 自动导入 Vue API、Pinia、Vue Router ,无需手动 import |
(2)使用ESLint
ESLint 是一个根据方案识别并报告 ECMAScript/JavaScript 代码问题的工具,其目的是使代码风格更加一致并避免错误。
1、安装并配置 ESLint
npm init @eslint/config
按照提示,选择你需要的配置,完成所有步骤后,项目下会自动生成eslint的配置文件,安装需要的依赖包。
2、添加.eslintignore忽略文件
在根目录创建文件,根据自己情况调整
node_modules
*.md
dist
.husky
**/*.md
**/*.svg
**/*.ejs
**/*.html
修改生成的配置文件
// eslint.config.mjs
import js from '@eslint/js'; // 导入 ESLint 官方 JavaScript 规则集
import tseslint from 'typescript-eslint'; // 导入 TypeScript ESLint 插件
import vue from 'eslint-plugin-vue'; // 导入 Vue 3 ESLint 插件
import prettier from 'eslint-config-prettier'; // 导入 Prettier 规则以关闭 ESLint 中与 Prettier 冲突的规则
/** @type {import('eslint').Linter.Config[]} */
export default [
{
// 指定 ESLint 需要检查的文件类型
files: ['**/*.{js,mjs,cjs,ts,vue}'],
// 配置 JavaScript 运行环境的全局变量和解析器选项
languageOptions: {
globals: { uni: 'readonly' }, // 声明 `uni` 为全局变量,且只读(适用于 UniApp)
parserOptions: {
ecmaVersion: 'latest', // 使用最新的 ECMAScript 语法
sourceType: 'module', // 代码采用 ES 模块方式(import/export)
parser: '@typescript-eslint/parser', // 使用 TypeScript ESLint 解析器,支持 TS 代码
},
},
},
// JavaScript 推荐规则(包括最佳实践、代码风格等)
js.configs.recommended,
// Vue 3 推荐规则(适用于 Vue 单文件组件)
...vue.configs['flat/recommended'],
// TypeScript 推荐规则(提供 TS 语法检查和类型规则)
...tseslint.configs.recommended,
// 兼容 Prettier(关闭与 Prettier 冲突的 ESLint 规则)
prettier,
{
// 自定义 ESLint 规则,覆盖默认配置
rules: {
'vue/attribute-hyphenation': 'off', // 允许 Vue 组件属性使用驼峰命名(例如 `myProp` 而不是 `my-prop`)
'no-var': 'warn', // 警告使用 `var`,建议使用 `let` 或 `const`
'@typescript-eslint/no-unused-vars': 'error', // 报错:不允许定义未使用的变量
'@typescript-eslint/no-empty-interface': 'off', // 允许定义空的 TypeScript 接口
'vue/multi-word-component-names': 'off', // 允许 Vue 组件名称是单个单词(默认要求组件名称至少两个单词)
'@typescript-eslint/no-empty-function': 'off', // 允许定义空函数
'@typescript-eslint/no-explicit-any': 'off', // 允许使用 `any` 类型(如果不希望使用 `any`,可以改成 `warn` 或 `error`)
},
},
];