Skip to content

组合式函数概览

介绍

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 - 认证与权限管理

提供用户认证与权限检查功能,包括权限字符串检查、角色校验和路由访问控制。

核心功能:

  • 登录状态判断: isLoggedInisSuperAdminisTenantAdmin
  • 权限检查: hasPermissionhasAllPermissions
  • 角色检查: hasRolehasAllRoles
  • 路由控制: canAccessRoutefilterAuthorizedRoutes
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 请求封装,支持请求拦截、响应处理、数据加密、错误处理等功能。

核心功能:

  • 请求方法: getpostputdel
  • 文件操作: uploaddownload
  • 链式调用: 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 - 字典数据管理

提供字典数据查询、缓存和标签获取功能,简化字典数据的使用。

核心功能:

  • 字典查询: getDictgetDictOptions
  • 标签获取: getDictLabelgetDictValue
  • 字典缓存: 自动缓存减少请求
  • 类型转换: 值与标签互转
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 - 支付功能管理

提供统一的支付功能封装,支持微信支付、支付宝支付、余额支付等多种支付方式。

核心功能:

  • 支付发起: paycreatePayment
  • 支付查询: queryPaymentStatusgetPaymentResult
  • 多平台支持: 微信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 连接管理功能,支持连接、断开、消息发送、事件监听等。

核心功能:

  • 连接管理: connectdisconnectreconnect
  • 消息操作: sendonoff
  • 自动重连: 断线自动重连
  • 心跳检测: 保持连接活跃
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.value

4. 错误处理

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
  }
}

组合式函数命名规范

  1. 文件命名: 使用 use 前缀 + 功能名称,如 useAuth.tsuseHttp.ts
  2. 导出命名: 与文件名保持一致,如 export const useAuth = () => {}
  3. 返回值: 返回对象,包含状态、方法、计算属性等
  4. 类型定义: 提供完整的 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/