组合式函数概览
介绍
RuoYi-Plus-UniApp 提供了一套完整的组合式函数(Composables),基于 Vue 3 Composition API 设计,封装了常用的业务逻辑和功能模块,帮助开发者快速构建功能丰富、可维护性高的移动应用。
核心特性:
- Vue 3 Composition API - 基于 Vue 3 组合式 API 设计,符合现代前端开发规范
- TypeScript 支持 - 完整的TypeScript类型定义,提供智能提示和类型检查
- 响应式设计 - 充分利用 Vue 3 响应式系统,实现状态自动更新
- 可复用性强 - 组合式函数设计,可在任意组件中灵活复用
- 状态管理集成 - 深度集成 Pinia 状态管理,简化全局状态操作
- 平台兼容 - 完美兼容 UniApp 多平台(H5、微信小程序、支付宝小程序、APP)
- 业务场景丰富 - 覆盖认证、HTTP请求、支付、字典、WebSocket等常见业务场景
- 错误处理完善 - 统一的错误处理机制,提高应用稳定性
源码位置: src/composables/
参考: src/composables/
主要组合式函数
1. useAuth - 认证与权限管理
提供用户认证与权限检查功能,包括权限字符串检查、角色校验和路由访问控制。
核心功能:
- 登录状态判断:
isLoggedIn、isSuperAdmin、isTenantAdmin - 权限检查:
hasPermission、hasAllPermissions - 角色检查:
hasRole、hasAllRoles - 路由控制:
canAccessRoute、filterAuthorizedRoutes
typescript
import { useAuth } from '@/composables/useAuth'
const { hasPermission, hasRole, isSuperAdmin } = useAuth()
// 检查权限
const canEdit = hasPermission('system:user:edit')
// 检查角色
const isAdmin = hasRole('admin')
// 检查是否为超级管理员
const isSuperAdminUser = isSuperAdmin()参考: src/composables/useAuth.ts:1-355
2. useHttp - HTTP 请求管理
提供统一的 HTTP 请求封装,支持请求拦截、响应处理、数据加密、错误处理等功能。
核心功能:
- 请求方法:
get、post、put、del - 文件操作:
upload、download - 链式调用:
noAuth()、encrypt()、skipWait()、timeout() - 自动处理: Token添加、租户信息、防重复提交、数据加密解密
typescript
import { http } from '@/composables/useHttp'
// GET 请求
const [error, data] = await http.get('/api/users')
// POST 请求
await http.post('/api/users', {
name: '张三'
})
// 链式调用 - 禁用认证 + 启用加密
const [err, result] = await http.noAuth().encrypt().post('/api/login', credentials)参考: src/composables/useHttp.ts:1-730
3. useDict - 字典数据管理
提供字典数据查询、缓存和标签获取功能,简化字典数据的使用。
核心功能:
- 字典查询:
getDict、getDictOptions - 标签获取:
getDictLabel、getDictValue - 字典缓存: 自动缓存减少请求
- 类型转换: 值与标签互转
typescript
import { useDict } from '@/composables/useDict'
const { getDict, getDictLabel } = useDict()
// 获取字典
const statusDict = await getDict('sys_status')
// 获取标签
const label = getDictLabel('sys_status', '1')参考: src/composables/useDict.ts
4. usePayment - 支付功能管理
提供统一的支付功能封装,支持微信支付、支付宝支付、余额支付等多种支付方式。
核心功能:
- 支付发起:
pay、createPayment - 支付查询:
queryPaymentStatus、getPaymentResult - 多平台支持: 微信JSAPI/Native/APP/H5、支付宝WAP/PAGE、余额支付
- 状态轮询: 自动轮询支付结果
typescript
import { usePayment } from '@/composables/usePayment'
const { pay } = usePayment()
// 发起支付
await pay({
orderId: '123',
paymentMethod: 'wechat'
})参考: src/composables/usePayment.ts
5. useWebSocket - WebSocket 连接管理
提供 WebSocket 连接管理功能,支持连接、断开、消息发送、事件监听等。
核心功能:
- 连接管理:
connect、disconnect、reconnect - 消息操作:
send、on、off - 自动重连: 断线自动重连
- 心跳检测: 保持连接活跃
typescript
import { useWebSocket } from '@/composables/useWebSocket'
const { connect, send, on } = useWebSocket('wss://example.com/ws')
// 连接
await connect()
// 监听消息
on('message', (data) => {
console.log('收到消息:', data)
})
// 发送消息
send({ type: 'chat', content: 'Hello' })参考: src/composables/useWebSocket.ts
6. 其他组合式函数
- useShare - 分享功能
- useEventBus - 事件总线
- useScroll - 滚动控制
- useTheme - 主题切换
- useToken - Token 管理
- useI18n - 国际化
- useAppInit - 应用初始化
- useSubscribe - 消息订阅
- useWxShare - 微信分享
使用示例
基本使用
typescript
import { useAuth } from '@/composables/useAuth'
export default defineComponent({
setup() {
const { hasPermission } = useAuth()
const canEdit = hasPermission('system:user:edit')
return { canEdit }
}
})组合使用
typescript
import { useAuth } from '@/composables/useAuth'
import { http } from '@/composables/useHttp'
const { hasPermission } = useAuth()
const loadData = async () => {
if (!hasPermission('data:list')) {
uni.showToast({ title: '无权限', icon: 'none' })
return
}
const [error, data] = await http.get('/api/data')
if (error) {
console.error('加载失败:', error)
return
}
console.log('数据:', data)
}最佳实践
1. 按需导入
typescript
// ✅ 推荐 - 按需导入
import { useAuth } from '@/composables/useAuth'
const { hasPermission } = useAuth()
// ❌ 不推荐 - 全量导入
import * as composables from '@/composables'2. 类型安全
typescript
// ✅ 推荐 - 使用泛型指定类型
interface User {
id: number
name: string
}
const [error, users] = await http.get<User[]>('/api/users')
// ❌ 不推荐 - 不指定类型
const [error, users] = await http.get('/api/users')3. 响应式使用
typescript
// ✅ 推荐 - 正确使用响应式
const { isLoggedIn } = useAuth()
watchEffect(() => {
if (isLoggedIn.value) {
console.log('已登录')
}
})
// ❌ 不推荐 - 直接访问值失去响应性
const loggedIn = isLoggedIn.value4. 错误处理
typescript
// ✅ 推荐 - 使用 to 函数处理错误
import { to } from '@/utils/to'
const [error, data] = await http.get('/api/users')
if (error) {
console.error('请求失败:', error)
uni.showToast({ title: error.message, icon: 'none' })
return
}
// 使用数据
console.log('用户列表:', data)
// ❌ 不推荐 - 使用 try-catch
try {
const data = await http.get('/api/users')
console.log(data)
} catch (error) {
console.error(error)
}5. 组合式函数复用
typescript
// ✅ 推荐 - 创建自定义组合式函数
export const useUserManagement = () => {
const { hasPermission } = useAuth()
const canEdit = computed(() => hasPermission('system:user:edit'))
const canDelete = computed(() => hasPermission('system:user:delete'))
const loadUsers = async () => {
const [error, users] = await http.get('/api/users')
return error ? [] : users
}
return {
canEdit,
canDelete,
loadUsers
}
}
// 在组件中使用
const { canEdit, canDelete, loadUsers } = useUserManagement()注意事项
1. setup 中使用
组合式函数必须在组件的 setup() 函数或 <script setup> 中调用:
typescript
// ✅ 正确
export default defineComponent({
setup() {
const { hasPermission } = useAuth() // ✓ 正确
return { hasPermission }
}
})
// ❌ 错误
export default defineComponent({
methods: {
checkPermission() {
const { hasPermission } = useAuth() // ✗ 错误
return hasPermission('some:permission')
}
}
})2. 响应式丢失
不要解构响应式对象,会导致响应性丢失:
typescript
// ❌ 错误 - 解构会丢失响应性
const { isLoggedIn } = useAuth()
const loggedIn = isLoggedIn.value // 丢失响应性
// ✅ 正确 - 使用 computed 或直接访问 .value
const { isLoggedIn } = useAuth()
const loggedIn = computed(() => isLoggedIn.value)3. 异步初始化
某些组合式函数可能需要异步初始化,确保在使用前完成初始化:
typescript
// ✅ 正确
const { connect, send } = useWebSocket('wss://example.com/ws')
onMounted(async () => {
await connect() // 等待连接完成
send({ type: 'hello' })
})
// ❌ 错误
const { connect, send } = useWebSocket('wss://example.com/ws')
connect() // 未等待完成
send({ type: 'hello' }) // 可能失败4. 内存泄漏
组件销毁时清理资源:
typescript
// ✅ 正确
const { connect, disconnect } = useWebSocket('wss://example.com/ws')
onMounted(() => {
connect()
})
onUnmounted(() => {
disconnect() // 清理连接
})
// ❌ 错误 - 未清理资源
const { connect } = useWebSocket('wss://example.com/ws')
onMounted(() => {
connect()
})
// 组件销毁时连接仍然存在5. Store 依赖
部分组合式函数依赖 Pinia Store,确保 Store 已正确初始化:
typescript
// ✅ 正确 - 在 app.use(pinia) 之后使用
const { hasPermission } = useAuth() // Store 已初始化
// ❌ 错误 - 在 Store 初始化前使用
// 可能导致获取不到用户信息扩展开发
创建自定义组合式函数
typescript
// composables/useCustomFeature.ts
export const useCustomFeature = () => {
// 响应式状态
const count = ref(0)
// 计算属性
const doubleCount = computed(() => count.value * 2)
// 方法
const increment = () => {
count.value++
}
// 生命周期
onMounted(() => {
console.log('组合式函数已挂载')
})
// 返回公开的属性和方法
return {
count,
doubleCount,
increment
}
}组合式函数命名规范
- 文件命名: 使用
use前缀 + 功能名称,如useAuth.ts、useHttp.ts - 导出命名: 与文件名保持一致,如
export const useAuth = () => {} - 返回值: 返回对象,包含状态、方法、计算属性等
- 类型定义: 提供完整的 TypeScript 类型定义
组合式函数最佳实践模板
typescript
/**
* 组合式函数描述
* @description 详细说明功能和用途
* @returns 返回值说明
* @example 使用示例
*/
export const useFeature = () => {
// 1. 响应式状态
const state = ref<State>({
// 状态定义
})
// 2. 计算属性
const computedValue = computed(() => {
// 计算逻辑
})
// 3. 方法定义
const method = async () => {
// 方法实现
}
// 4. 生命周期钩子
onMounted(() => {
// 初始化逻辑
})
onUnmounted(() => {
// 清理逻辑
})
// 5. 返回公开API
return {
// 状态
state: readonly(state), // 只读状态
// 计算属性
computedValue,
// 方法
method
}
}通过合理使用这些组合式函数,可以大幅提升开发效率,减少重复代码,提高代码可维护性。
参考: src/composables/
