【RuoYi-SpringBoot3-UniApp】:一套代码,多端运行的移动端开发方案
一、项目简介
RuoYi-SpringBoot3-UniApp 是基于 UniApp 开发的跨平台移动端项目,一套代码可同时发布到微信小程序、App(Android/iOS)、H5 和桌面端,显著降低开发成本和维护难度。
核心特点:
- ✅ 一套代码,多端运行(小程序、App、H5、桌面端)
- ✅ 基于 Vue3 组合式 API,代码更简洁
- ✅ 内置完整认证体系和权限管理
- ✅ 集成主流 UI 组件库(uni-ui)
- ✅ 支持 Electron 打包为桌面应用
二、核心功能特性
3.1 完整的认证体系
JWT Token 认证流程:
javascript
// 1. 登录获取 Token
login(username, password)
→ 后端返回 Token
→ 存储到本地
// 2. 请求自动携带 Token
request(url)
→ 拦截器添加 Token 到 Header
→ 发送请求
// 3. Token 失效处理
Token 过期
→ 拦截器检测 401
→ 自动跳转登录页
核心特性:
- ✅ 记住密码(下次自动登录)
- ✅ RSA 加密传输(密码不明文)
- ✅ 路由拦截(未登录自动跳转)
- ✅ 白名单机制(部分页面无需登录)
3.2 路由守卫 ------ 权限控制核心
javascript
// permission.js
const loginPage = "/pages/login"
// 白名单:这些页面无需登录
const whiteList = [
'/pages/login', // 登录页
'/pages/register', // 注册页
'/pages/common/webview/index' // 网页浏览
]
// 页面跳转时自动拦截
uni.addInterceptor('navigateTo', {
invoke(e) {
const token = getToken()
// 没有 Token 且不在白名单 → 跳转登录
if (!token && !whiteList.includes(e.url)) {
uni.navigateTo({ url: loginPage })
return false
}
return true
}
})
实现效果:
- 用户未登录访问"我的"页面 → 自动跳转登录页
- 登录成功后 → 自动跳转回原页面
- 退出登录 → 清除 Token,跳转登录页
3.3 Pinia 状态管理 ------ 告别混乱
为什么需要状态管理?
没有状态管理时:
css
组件 A 修改用户信息
→ 需要通过事件通知组件 B
→ 再通知组件 C
→ 代码混乱,难以维护
有状态管理后:
css
组件 A 修改 Store 中的用户信息
→ 所有组件自动更新
→ 代码清晰,易于维护
实际代码:
javascript
// store/modules/user.js
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
token: '',
userInfo: {}
}),
actions: {
// 登录
login(username, password) {
return loginApi(username, password).then(res => {
this.token = res.token
this.userInfo = res.user
})
},
// 退出
logout() {
this.token = ''
this.userInfo = {}
removeToken()
}
}
})
在组件中使用:
vue
<template>
<view>{{ userStore.userInfo.nickName }}</view>
<button @click="handleLogout">退出登录</button>
</template>
<script setup>
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
const handleLogout = () => {
userStore.logout()
uni.navigateTo({ url: '/pages/login' })
}
</script>
四、实用插件生态
4.1 z-paging ------ 列表分页终极方案
痛点: 传统列表开发需要手动处理:
- 下拉刷新逻辑
- 上拉加载更多
- 加载状态管理
- 空数据提示
- 网络错误处理
解决方案: z-paging 一站式解决。
vue
<template>
<z-paging
ref="paging"
v-model="dataList"
@query="queryList"
>
<!-- 自动处理下拉刷新、上拉加载 -->
<view v-for="item in dataList" :key="item.id">
<text>{{ item.name }}</text>
</view>
</z-paging>
</template>
<script setup>
import { ref } from 'vue'
import { getUserList } from '@/api/system/user'
const paging = ref(null)
const dataList = ref([])
// 查询列表(分页自动处理)
const queryList = (pageNo, pageSize) => {
getUserList({ pageNo, pageSize }).then(res => {
// 告诉 z-paging 数据加载完成
paging.value.complete(res.rows)
})
}
</script>
效果:
- ✅ 首次加载显示 loading
- ✅ 下拉刷新自动重置页码
- ✅ 上拉加载更多自动翻页
- ✅ 没有更多数据自动提示
- ✅ 加载失败自动显示错误
4.2 mp-html ------ 富文本渲染神器
跨平台难题: 不同平台的富文本渲染能力差异巨大。
| 平台 | 原生支持 | 问题 |
|---|---|---|
| H5 | <div v-html> |
简单但不安全 |
| 微信小程序 | <rich-text> |
功能有限 |
| App | 无原生支持 | 需要 WebView |
mp-html 统一方案:
vue
<template>
<!-- 所有平台统一使用 -->
<mp-html :content="htmlContent" />
</template>
<script setup>
import { ref } from 'vue'
const htmlContent = ref(`
<h1>标题</h1>
<p>段落文本</p>
<img src="xxx.jpg" />
<table>...</table>
`)
</script>
核心优势:
- ✅ 所有平台统一渲染效果
- ✅ 支持 HTML 标签和 CSS
- ✅ 支持图片懒加载
- ✅ 支持视频播放
- ✅ 自动适配屏幕宽度
4.3 uni-ui ------ 官方组件库
50+ 精选组件,覆盖常见场景:
vue
<template>
<!-- 表单组件 -->
<uni-forms :model="form">
<uni-forms-item label="用户名">
<uni-easyinput v-model="form.username" />
</uni-forms-item>
</uni-forms>
<!-- 列表组件 -->
<uni-list>
<uni-list-item title="标题" note="描述" />
</uni-list>
<!-- 弹窗组件 -->
<uni-popup ref="popup">
<view>弹窗内容</view>
</uni-popup>
<!-- 日历组件 -->
<uni-calendar @change="onChange" />
</template>
五、条件编译 ------ 跨平台兼容的利器
问题: 不同平台有不同的 API 和表现。
解决方案: UniApp 的条件编译机制。
5.1 模板条件编译
vue
<template>
<!-- 仅在微信小程序显示 -->
<!-- #ifdef MP-WEIXIN -->
<button open-type="getUserInfo">授权登录</button>
<!-- #endif -->
<!-- 仅在 H5 显示 -->
<!-- #ifdef H5 -->
<input type="text" placeholder="请输入账号" />
<!-- #endif -->
<!-- 仅在 App 显示 -->
<!-- #ifdef APP-PLUS -->
<view @click="scanCode">扫码登录</view>
<!-- #endif -->
<!-- 除了微信小程序,其他平台都显示 -->
<!-- #ifndef MP-WEIXIN -->
<view>通用登录方式</view>
<!-- #endif -->
</template>
5.2 JavaScript 条件编译
javascript
<script>
// 微信小程序特有逻辑
// #ifdef MP-WEIXIN
const login = () => {
wx.login({
success: res => console.log(res.code)
})
}
// #endif
// H5 特有逻辑
// #ifdef H5
const login = () => {
window.location.href = '/oauth/login'
}
// #endif
// App 特有逻辑
// #ifdef APP-PLUS
const login = () => {
plus.oauth.getServices(services => {
// 调用原生登录
})
}
// #endif
</script>
5.3 样式条件编译
css
<style>
/* 微信小程序 */
/* #ifdef MP-WEIXIN */
.title {
font-size: 28rpx;
color: #07c160; /* 微信绿 */
}
/* #endif */
/* H5 */
/* #ifdef H5 */
.title {
font-size: 16px;
color: #409eff; /* Element Blue */
}
/* #endif */
</style>
六、Electron 桌面端 ------ 锦上添花
为什么需要桌面端?
场景: 企业内部管理系统,员工希望有独立的桌面应用,不想每次都打开浏览器输入网址。
方案: 将 UniApp H5 打包成桌面应用。
使用步骤
bash
# 1. 构建 H5 版本
npm run build:h5
# 2. 进入 electron 目录
cd electron
# 3. 安装依赖
npm install
# 4. 开发模式(加载本地服务)
npm run dev
# 5. 生产模式(加载打包后的 H5)
npm run prod
核心配置
javascript
// electron/main.js
const { app, BrowserWindow } = require('electron')
app.whenReady().then(() => {
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true
}
})
// 开发模式:加载本地服务
if (process.env.NODE_ENV === 'development') {
win.loadURL('http://localhost:5173')
}
// 生产模式:加载打包的 H5 文件
else {
win.loadFile('../dist/index.html')
}
})
优势:
- ✅ 支持 Windows、macOS、Linux
- ✅ 原生窗口体验(有菜单、图标、快捷键)
- ✅ 可调用 Node.js 能力(文件操作、系统通知等)
- ✅ 开发调试方便(内置开发者工具)
七、快速开始
7.1 环境准备
bash
# 必需
Node.js 20+
HBuilderX(UniApp 官方 IDE)
# 可选(根据目标平台)
微信开发者工具(开发小程序)
Android Studio(开发 Android App)
Xcode(开发 iOS App,仅 macOS)
7.2 三步启动
第一步:克隆并安装
bash
git clone https://github.com/undsky/RuoYi-SpringBoot3-UniApp.git
cd RuoYi-SpringBoot3-UniApp
npm install
第二步:配置后端地址
javascript
// config.js
export default {
baseUrl: 'http://localhost:8087', // 修改为你的后端地址
}
第三步:运行项目
- 用 HBuilderX 打开项目
- 点击"运行" → 选择平台:
- 运行到浏览器(H5)
- 运行到小程序模拟器
- 运行到手机或模拟器(App)
访问系统:
- H5:
http://localhost:5173 - 小程序:在微信开发者工具中预览
- App:在模拟器或真机中查看
八、项目结构
perl
RuoYi-SpringBoot3-UniApp/
├── api/ # API 接口
│ ├── login.js # 登录接口
│ └── system/ # 系统模块接口
├── components/ # 全局组件
├── electron/ # Electron 桌面应用
│ ├── main.js # 主进程
│ └── package.json # 依赖配置
├── pages/ # 页面目录
│ ├── index.vue # 首页
│ ├── login.vue # 登录页
│ ├── work/ # 工作台模块
│ └── mine/ # 个人中心模块
├── plugins/ # 插件封装
│ ├── auth.js # 权限插件
│ ├── modal.js # 消息提示
│ └── tab.js # 标签页管理
├── store/ # 状态管理(Pinia)
│ ├── index.js # Store 入口
│ └── modules/ # Store 模块
├── uni_modules/ # UniApp 插件
│ ├── uni-ui/ # UI 组件库
│ ├── z-paging/ # 分页组件
│ └── mp-html/ # 富文本组件
├── utils/ # 工具库
│ ├── request.js # 请求封装
│ ├── auth.js # 认证工具
│ └── storage.js # 存储工具
├── App.vue # 应用入口
├── main.js # 入口文件
├── pages.json # 页面路由配置
├── manifest.json # 应用配置
├── permission.js # 路由守卫
└── config.js # 全局配置
十一、总结
RuoYi-SpringBoot3-UniApp 是一个生产就绪的跨平台移动端解决方案。
核心优势:
-
真正的跨平台
- 一套代码,5 个平台
- 开发成本降低 70%
- 维护更简单
-
现代化技术栈
- Vue 3 组合式 API
- Pinia 状态管理
- TypeScript 支持(可选)
-
完善的功能
- 认证体系(JWT + RSA)
- 路由守卫(权限控制)
- 状态管理(Pinia)
-
丰富的插件
- z-paging(分页方案)
- mp-html(富文本)
- uni-ui(50+ 组件)
-
开箱即用
- 登录注册
- 个人中心
- 工作台
- 权限管理