useTableSelection
表格行选择管理 Composable,提供统一的表格选择逻辑。
功能介绍
useTableSelection 封装了表格多选的常用逻辑:
- 管理选中的 ID 列表
- 处理选择变化事件
- 清空选择
- 检查是否选中
- 获取选中数量
基本用法
vue
<template>
<el-table
:data="tableData"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="50" />
<el-table-column prop="name" label="姓名" />
<el-table-column prop="email" label="邮箱" />
</el-table>
<div class="toolbar">
<span>已选择 {{ selectedCount }} 条</span>
<el-button
:disabled="!hasSelection"
@click="handleBatchDelete"
>
批量删除
</el-button>
<el-button @click="clearSelection">清空选择</el-button>
</div>
</template>
<script setup lang="ts">
import { useTableSelection } from '@/composables'
interface UserVO {
id: number
name: string
email: string
}
const tableData = ref<UserVO[]>([])
const {
selectedIds,
selectedCount,
hasSelection,
handleSelectionChange,
clearSelection
} = useTableSelection<UserVO>()
async function handleBatchDelete() {
if (!hasSelection.value) {
ElMessage.warning('请选择要删除的数据')
return
}
await UserAPI.deleteByIds(selectedIds.value)
ElMessage.success('删除成功')
clearSelection()
fetchData()
}
</script>类型定义
typescript
function useTableSelection<T extends { id: string | number }>(): {
/** 选中的 ID 列表 */
selectedIds: Ref<(string | number)[]>
/** 选中的数量 */
selectedCount: ComputedRef<number>
/** 是否有选中项 */
hasSelection: ComputedRef<boolean>
/** 处理选择变化 */
handleSelectionChange: (selection: T[]) => void
/** 清空选择 */
clearSelection: () => void
/** 检查指定 ID 是否被选中 */
isSelected: (id: string | number) => boolean
}返回值
| 名称 | 类型 | 说明 |
|---|---|---|
| selectedIds | Ref<(string | number)[]> | 选中的 ID 数组 |
| selectedCount | ComputedRef<number> | 选中的数量 |
| hasSelection | ComputedRef<boolean> | 是否有选中项 |
| handleSelectionChange | (selection: T[]) => void | 处理选择变化 |
| clearSelection | () => void | 清空选择 |
| isSelected | (id) => boolean | 检查是否选中 |
泛型约束
数据项类型必须包含 id 属性:
typescript
// ✅ 正确
interface UserVO {
id: number
name: string
}
const { selectedIds } = useTableSelection<UserVO>()
// ❌ 错误:缺少 id 属性
interface Item {
name: string
}
const { selectedIds } = useTableSelection<Item>() // 类型错误配合 CURD 组件使用
vue
<template>
<page-content
ref="contentRef"
:content-config="contentConfig"
@selection-change="handleSelectionChange"
/>
<el-button
:disabled="!hasSelection"
@click="handleBatchExport"
>
导出选中 ({{ selectedCount }})
</el-button>
</template>
<script setup lang="ts">
import { useTableSelection } from '@/composables'
const {
selectedIds,
selectedCount,
hasSelection,
handleSelectionChange,
clearSelection
} = useTableSelection()
async function handleBatchExport() {
await exportData(selectedIds.value)
clearSelection()
}
</script>高级用法
自定义主键字段
如果数据的主键不是 id,可以在处理函数中转换:
typescript
interface OrderVO {
orderId: string
orderNo: string
}
const selectedOrderIds = ref<string[]>([])
function handleSelectionChange(selection: OrderVO[]) {
selectedOrderIds.value = selection.map(item => item.orderId)
}跨页选择
配合表格的 row-key 和 reserve-selection 实现跨页选择:
vue
<template>
<el-table
:data="tableData"
:row-key="row => row.id"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="50"
:reserve-selection="true"
/>
</el-table>
</template>注意事项
- 泛型类型:确保传入的泛型类型包含
id属性 - 清空时机:删除或其他操作后记得调用
clearSelection() - 响应式:
selectedIds是响应式的,可以直接在模板中使用
