236 lines
6.8 KiB
Markdown
236 lines
6.8 KiB
Markdown
# DataTable 组件使用指南
|
|||
|
|
|
||
|
|
## 概述
|
||
|
|
|
||
|
|
`DataTable` 是一个基于 Arco Design Vue 的 `a-table` 组件封装,提供了统一的分页配置和事件处理,可以在多个页面中复用。
|
||
|
|
|
||
|
|
## 特性
|
||
|
|
|
||
|
|
- 🚀 统一的分页配置
|
||
|
|
- 📊 支持自定义列配置
|
||
|
|
- 🔄 内置加载状态管理
|
||
|
|
- 🎯 支持排序和筛选
|
||
|
|
- 📱 响应式设计
|
||
|
|
- 🎨 可自定义样式
|
||
|
|
|
||
|
|
## 基础用法
|
||
|
|
|
||
|
|
### 1. 使用 DataTable 组件
|
||
|
|
|
||
|
|
```vue
|
||
|
|
<template>
|
||
|
|
<DataTable
|
||
|
|
:data="tableData"
|
||
|
|
:columns="columns"
|
||
|
|
:loading="loading"
|
||
|
|
:total="total"
|
||
|
|
:current="current"
|
||
|
|
:page-size="pageSize"
|
||
|
|
@page-change="handlePageChange"
|
||
|
|
@page-size-change="handlePageSizeChange"
|
||
|
|
>
|
||
|
|
<!-- 自定义列插槽 -->
|
||
|
|
<template #status="{ record }">
|
||
|
|
<a-tag :color="record.status === 'active' ? 'green' : 'red'">
|
||
|
|
{{ record.status }}
|
||
|
|
</a-tag>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<template #operate="{ record }">
|
||
|
|
<a-space>
|
||
|
|
<a-button size="small">查看</a-button>
|
||
|
|
<a-button size="small" type="primary">编辑</a-button>
|
||
|
|
</a-space>
|
||
|
|
</template>
|
||
|
|
</DataTable>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { ref, onMounted } from 'vue';
|
||
|
|
import type { TableColumnData, TableData } from '@arco-design/web-vue';
|
||
|
|
import useDataTable from '@/composables/useDataTable';
|
||
|
|
|
||
|
|
// 使用 DataTable composable
|
||
|
|
const {
|
||
|
|
data: tableData,
|
||
|
|
columns,
|
||
|
|
loading,
|
||
|
|
total,
|
||
|
|
current,
|
||
|
|
pageSize,
|
||
|
|
setData,
|
||
|
|
setColumns,
|
||
|
|
setLoading,
|
||
|
|
setTotal,
|
||
|
|
setCurrent,
|
||
|
|
setPageSize,
|
||
|
|
} = useDataTable({
|
||
|
|
initialPage: 1,
|
||
|
|
initialPageSize: 10,
|
||
|
|
pageSizeOptions: [10, 20, 50, 100],
|
||
|
|
});
|
||
|
|
|
||
|
|
// 列配置
|
||
|
|
const columnConfig: TableColumnData[] = [
|
||
|
|
{ title: '姓名', dataIndex: 'name', key: 'name' },
|
||
|
|
{ title: '年龄', dataIndex: 'age', key: 'age' },
|
||
|
|
{ title: '状态', dataIndex: 'status', key: 'status', slotName: 'status' },
|
||
|
|
{ title: '操作', key: 'operate', slotName: 'operate', width: 200 },
|
||
|
|
];
|
||
|
|
|
||
|
|
// 模拟数据
|
||
|
|
const mockData: TableData[] = [
|
||
|
|
{ id: 1, name: '张三', age: 25, status: 'active' },
|
||
|
|
{ id: 2, name: '李四', age: 30, status: 'inactive' },
|
||
|
|
];
|
||
|
|
|
||
|
|
onMounted(() => {
|
||
|
|
setColumns(columnConfig);
|
||
|
|
setData(mockData);
|
||
|
|
setTotal(mockData.length);
|
||
|
|
});
|
||
|
|
|
||
|
|
// 分页事件处理
|
||
|
|
const handlePageChange = (page: number) => {
|
||
|
|
setCurrent(page);
|
||
|
|
// 调用 API 获取数据
|
||
|
|
fetchData(page, pageSize.value);
|
||
|
|
};
|
||
|
|
|
||
|
|
const handlePageSizeChange = (pageSize: number) => {
|
||
|
|
setPageSize(pageSize);
|
||
|
|
// 调用 API 获取数据
|
||
|
|
fetchData(1, pageSize);
|
||
|
|
};
|
||
|
|
|
||
|
|
const fetchData = async (page: number, size: number) => {
|
||
|
|
setLoading(true);
|
||
|
|
try {
|
||
|
|
// 调用 API
|
||
|
|
// const { data, total } = await api.getList({ page, size });
|
||
|
|
// setData(data);
|
||
|
|
// setTotal(total);
|
||
|
|
} finally {
|
||
|
|
setLoading(false);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. 高级配置
|
||
|
|
|
||
|
|
```vue
|
||
|
|
<template>
|
||
|
|
<DataTable
|
||
|
|
:data="tableData"
|
||
|
|
:columns="columns"
|
||
|
|
:loading="loading"
|
||
|
|
:total="total"
|
||
|
|
:current="current"
|
||
|
|
:page-size="pageSize"
|
||
|
|
:bordered="true"
|
||
|
|
:stripe="true"
|
||
|
|
:size="'small'"
|
||
|
|
:scroll="{ x: 1200, y: 400 }"
|
||
|
|
@page-change="handlePageChange"
|
||
|
|
@page-size-change="handlePageSizeChange"
|
||
|
|
@selection-change="handleSelectionChange"
|
||
|
|
@sorter-change="handleSorterChange"
|
||
|
|
@filter-change="handleFilterChange"
|
||
|
|
>
|
||
|
|
<!-- 插槽内容 -->
|
||
|
|
</DataTable>
|
||
|
|
</template>
|
||
|
|
```
|
||
|
|
|
||
|
|
## Props 说明
|
||
|
|
|
||
|
|
| 属性 | 类型 | 默认值 | 说明 |
|
||
|
|
|------|------|--------|------|
|
||
|
|
| data | TableData[] | [] | 表格数据 |
|
||
|
|
| columns | TableColumnData[] | [] | 列配置 |
|
||
|
|
| loading | boolean | false | 加载状态 |
|
||
|
|
| rowKey | string | 'id' | 行键 |
|
||
|
|
| pagination | boolean \| PaginationProps | true | 分页配置 |
|
||
|
|
| bordered | boolean | false | 是否显示边框 |
|
||
|
|
| size | 'mini' \| 'small' \| 'medium' \| 'large' | 'medium' | 表格大小 |
|
||
|
|
| stripe | boolean | false | 是否显示斑马纹 |
|
||
|
|
| tableLayout | 'auto' \| 'fixed' | 'auto' | 表格布局 |
|
||
|
|
| scroll | object | - | 滚动配置 |
|
||
|
|
| current | number | 1 | 当前页码 |
|
||
|
|
| pageSize | number | 10 | 每页条数 |
|
||
|
|
| total | number | 0 | 总条数 |
|
||
|
|
| showTotal | boolean | true | 是否显示总数 |
|
||
|
|
| pageSizeOptions | number[] | [10, 20, 50, 100] | 每页条数选项 |
|
||
|
|
| showJumper | boolean | true | 是否显示快速跳转 |
|
||
|
|
| showPageSize | boolean | true | 是否显示每页条数选择器 |
|
||
|
|
|
||
|
|
## Events 说明
|
||
|
|
|
||
|
|
| 事件名 | 参数 | 说明 |
|
||
|
|
|--------|------|------|
|
||
|
|
| page-change | (page: number) | 页码变化 |
|
||
|
|
| page-size-change | (pageSize: number) | 每页条数变化 |
|
||
|
|
| selection-change | (selection: TableData[]) | 选择变化 |
|
||
|
|
| sorter-change | (sorter: any) | 排序变化 |
|
||
|
|
| filter-change | (filters: any) | 筛选变化 |
|
||
|
|
|
||
|
|
## useDataTable Composable
|
||
|
|
|
||
|
|
`useDataTable` 是一个用于管理表格状态的 composable,提供了以下功能:
|
||
|
|
|
||
|
|
### 返回值
|
||
|
|
|
||
|
|
| 属性 | 类型 | 说明 |
|
||
|
|
|------|------|------|
|
||
|
|
| data | TableData[] | 表格数据 |
|
||
|
|
| columns | TableColumnData[] | 列配置 |
|
||
|
|
| loading | boolean | 加载状态 |
|
||
|
|
| pagination | PaginationProps | 分页配置 |
|
||
|
|
| current | number | 当前页码 |
|
||
|
|
| pageSize | number | 每页条数 |
|
||
|
|
| total | number | 总条数 |
|
||
|
|
| setData | (data: TableData[]) => void | 设置数据 |
|
||
|
|
| setColumns | (columns: TableColumnData[]) => void | 设置列配置 |
|
||
|
|
| setLoading | (loading: boolean) => void | 设置加载状态 |
|
||
|
|
| setTotal | (total: number) => void | 设置总条数 |
|
||
|
|
| setCurrent | (current: number) => void | 设置当前页码 |
|
||
|
|
| setPageSize | (pageSize: number) => void | 设置每页条数 |
|
||
|
|
| resetPagination | () => void | 重置分页 |
|
||
|
|
|
||
|
|
### 配置选项
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface UseDataTableOptions {
|
||
|
|
initialPage?: number; // 初始页码
|
||
|
|
initialPageSize?: number; // 初始每页条数
|
||
|
|
pageSizeOptions?: number[]; // 每页条数选项
|
||
|
|
showTotal?: boolean; // 是否显示总数
|
||
|
|
showJumper?: boolean; // 是否显示快速跳转
|
||
|
|
showPageSize?: boolean; // 是否显示每页条数选择器
|
||
|
|
rowKey?: string; // 行键
|
||
|
|
bordered?: boolean; // 是否显示边框
|
||
|
|
size?: 'mini' | 'small' | 'medium' | 'large'; // 表格大小
|
||
|
|
stripe?: boolean; // 是否显示斑马纹
|
||
|
|
tableLayout?: 'auto' | 'fixed'; // 表格布局
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 最佳实践
|
||
|
|
|
||
|
|
1. **统一使用 DataTable 组件**:在项目中统一使用 DataTable 组件,避免重复配置分页逻辑。
|
||
|
|
|
||
|
|
2. **使用 useDataTable composable**:利用 composable 管理表格状态,提高代码复用性。
|
||
|
|
|
||
|
|
3. **合理配置列插槽**:对于需要自定义渲染的列,使用插槽进行自定义。
|
||
|
|
|
||
|
|
4. **处理加载状态**:在数据请求时正确设置 loading 状态。
|
||
|
|
|
||
|
|
5. **分页事件处理**:在分页事件中调用 API 获取对应页的数据。
|
||
|
|
|
||
|
|
## 注意事项
|
||
|
|
|
||
|
|
1. 确保在 `main.ts` 中注册了 `DataTable` 组件。
|
||
|
|
2. 列配置中的 `slotName` 要与模板中的插槽名称一致。
|
||
|
|
3. 数据源需要包含 `rowKey` 指定的字段。
|
||
|
|
4. 分页事件处理中应该调用实际的 API 接口。
|