add fiel
This commit is contained in:
293
src/components/TableColumnControl/QUICK_START.md
Normal file
293
src/components/TableColumnControl/QUICK_START.md
Normal file
@@ -0,0 +1,293 @@
|
||||
# TableColumnControl 快速开始指南
|
||||
|
||||
## 简介
|
||||
|
||||
`TableColumnControl` 是一个通用的表格列控制组件,支持:
|
||||
- ✅ 列的显示/隐藏控制
|
||||
- ✅ 列的拖拽排序
|
||||
- ✅ 配置的自动保存和恢复(基于路由)
|
||||
- ✅ 两种使用方式:自动提取或手动配置
|
||||
|
||||
## 快速集成(3 步)
|
||||
|
||||
### 步骤 1: 在页面中引入组件
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import type { TableInstance } from 'element-plus'
|
||||
|
||||
const tableRef = ref<TableInstance>()
|
||||
</script>
|
||||
```
|
||||
|
||||
### 步骤 2: 添加列设置按钮
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<!-- 列设置按钮(放在表格上方) -->
|
||||
<right-toolbar>
|
||||
<TableColumnControl
|
||||
:table-ref="tableRef"
|
||||
trigger-circle
|
||||
>
|
||||
<template #trigger>
|
||||
<el-tooltip content="列设置" placement="top">
|
||||
<el-button circle style="margin-left: 0;">
|
||||
<el-icon><Menu /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</TableColumnControl>
|
||||
</right-toolbar>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table ref="tableRef" :data="tableData">
|
||||
<el-table-column prop="name" label="姓名" />
|
||||
<el-table-column prop="age" label="年龄" />
|
||||
<el-table-column prop="email" label="邮箱" />
|
||||
<el-table-column label="操作" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button @click="handleEdit(scope.row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 步骤 3: 完成!
|
||||
|
||||
就这么简单!组件会自动:
|
||||
- 从表格中提取列配置
|
||||
- 根据当前路由自动生成存储 key
|
||||
- 保存和恢复用户的列设置
|
||||
|
||||
## 手动配置方式(可选)
|
||||
|
||||
如果你的表格列是动态生成的,或者需要自定义列配置,可以使用手动配置:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<right-toolbar>
|
||||
<TableColumnControl
|
||||
:columns="tableColumns"
|
||||
v-model="visibleColumns"
|
||||
trigger-circle
|
||||
>
|
||||
<template #trigger>
|
||||
<el-tooltip content="列设置" placement="top">
|
||||
<el-button circle>
|
||||
<el-icon><Menu /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</TableColumnControl>
|
||||
</right-toolbar>
|
||||
|
||||
<el-table :data="tableData">
|
||||
<el-table-column
|
||||
v-for="col in sortedTableColumns"
|
||||
v-if="checkColumnVisible(col.prop || '')"
|
||||
:key="col.prop"
|
||||
:prop="col.prop"
|
||||
:label="col.label"
|
||||
/>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const visibleColumns = ref<string[]>([])
|
||||
const columnOrder = ref<string[]>([])
|
||||
|
||||
const tableColumns = [
|
||||
{ prop: 'name', label: '姓名' },
|
||||
{ prop: 'age', label: '年龄' },
|
||||
{ prop: 'email', label: '邮箱' },
|
||||
{ prop: 'action', label: '操作', fixed: true, alwaysShow: true }
|
||||
]
|
||||
|
||||
// 检查列是否可见
|
||||
const checkColumnVisible = (prop: string): boolean => {
|
||||
if (visibleColumns.value.length === 0) return true
|
||||
return visibleColumns.value.includes(prop)
|
||||
}
|
||||
|
||||
// 排序后的列
|
||||
const sortedTableColumns = computed(() => {
|
||||
if (columnOrder.value.length === 0) return tableColumns
|
||||
|
||||
const ordered: typeof tableColumns = []
|
||||
const unordered: typeof tableColumns = []
|
||||
|
||||
columnOrder.value.forEach(key => {
|
||||
const col = tableColumns.find(c => (c.prop || c.label) === key)
|
||||
if (col) ordered.push(col)
|
||||
})
|
||||
|
||||
tableColumns.forEach(col => {
|
||||
const key = col.prop || col.label
|
||||
if (!columnOrder.value.includes(key)) {
|
||||
unordered.push(col)
|
||||
}
|
||||
})
|
||||
|
||||
return [...ordered, ...unordered]
|
||||
})
|
||||
|
||||
// 加载保存的配置
|
||||
const loadSavedConfig = () => {
|
||||
const routePath = route.path.replace(/^\//, '').replace(/\//g, '-')
|
||||
const storageKey = `table-columns-${routePath}`
|
||||
const saved = localStorage.getItem(storageKey)
|
||||
|
||||
if (saved) {
|
||||
try {
|
||||
const savedColumns = JSON.parse(saved)
|
||||
const validColumns = tableColumns
|
||||
.filter(col => !col.alwaysShow && !col.fixed)
|
||||
.map(col => col.prop || col.label)
|
||||
const filteredSaved = savedColumns.filter((col: string) => validColumns.includes(col))
|
||||
|
||||
if (filteredSaved.length > 0) {
|
||||
visibleColumns.value = filteredSaved
|
||||
} else {
|
||||
visibleColumns.value = validColumns
|
||||
}
|
||||
} catch (e) {
|
||||
visibleColumns.value = tableColumns
|
||||
.filter(col => !col.alwaysShow && !col.fixed)
|
||||
.map(col => col.prop || col.label)
|
||||
}
|
||||
} else {
|
||||
visibleColumns.value = tableColumns
|
||||
.filter(col => !col.alwaysShow && !col.fixed)
|
||||
.map(col => col.prop || col.label)
|
||||
}
|
||||
|
||||
// 加载排序
|
||||
const orderKey = `${storageKey}-order`
|
||||
const savedOrder = localStorage.getItem(orderKey)
|
||||
if (savedOrder) {
|
||||
try {
|
||||
columnOrder.value = JSON.parse(savedOrder)
|
||||
} catch (e) {
|
||||
columnOrder.value = tableColumns
|
||||
.filter(col => !col.alwaysShow && !col.fixed)
|
||||
.map(col => col.prop || col.label)
|
||||
}
|
||||
} else {
|
||||
columnOrder.value = tableColumns
|
||||
.filter(col => !col.alwaysShow && !col.fixed)
|
||||
.map(col => col.prop || col.label)
|
||||
}
|
||||
}
|
||||
|
||||
// 监听列变化
|
||||
const handleColumnChange = (columns: string[]) => {
|
||||
visibleColumns.value = columns
|
||||
const routePath = route.path.replace(/^\//, '').replace(/\//g, '-')
|
||||
const storageKey = `table-columns-${routePath}`
|
||||
const selectableColumns = columns.filter(col => {
|
||||
const column = tableColumns.find(c => (c.prop || c.label) === col)
|
||||
return column && !column.alwaysShow && !column.fixed
|
||||
})
|
||||
localStorage.setItem(storageKey, JSON.stringify(selectableColumns))
|
||||
}
|
||||
|
||||
// 监听列排序变化
|
||||
const handleColumnOrderChange = (order: string[]) => {
|
||||
columnOrder.value = order
|
||||
const routePath = route.path.replace(/^\//, '').replace(/\//g, '-')
|
||||
const storageKey = `table-columns-${routePath}-order`
|
||||
localStorage.setItem(storageKey, JSON.stringify(order))
|
||||
}
|
||||
|
||||
// 立即加载配置
|
||||
loadSavedConfig()
|
||||
</script>
|
||||
```
|
||||
|
||||
## 使用 Composable(推荐)
|
||||
|
||||
为了简化手动配置方式,可以使用 `useTableColumnControl` composable:
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import { useTableColumnControl } from '/@/composables/useTableColumnControl'
|
||||
|
||||
const tableColumns = [
|
||||
{ prop: 'name', label: '姓名' },
|
||||
{ prop: 'age', label: '年龄' },
|
||||
{ prop: 'email', label: '邮箱' },
|
||||
{ prop: 'action', label: '操作', fixed: true, alwaysShow: true }
|
||||
]
|
||||
|
||||
const {
|
||||
visibleColumns,
|
||||
columnOrder,
|
||||
checkColumnVisible,
|
||||
saveColumnConfig,
|
||||
saveColumnOrder
|
||||
} = useTableColumnControl({
|
||||
columns: tableColumns
|
||||
})
|
||||
|
||||
const sortedTableColumns = computed(() => {
|
||||
// ... 排序逻辑
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 如何自定义存储 key?
|
||||
|
||||
```vue
|
||||
<TableColumnControl
|
||||
:table-ref="tableRef"
|
||||
storage-key="my-custom-key"
|
||||
/>
|
||||
```
|
||||
|
||||
### Q: 如何设置始终显示的列?
|
||||
|
||||
```vue
|
||||
<TableColumnControl
|
||||
:table-ref="tableRef"
|
||||
:auto-extract-options="{
|
||||
alwaysShow: ['name', 'action']
|
||||
}"
|
||||
/>
|
||||
```
|
||||
|
||||
### Q: 如何设置默认隐藏的列?
|
||||
|
||||
```vue
|
||||
<TableColumnControl
|
||||
:table-ref="tableRef"
|
||||
:auto-extract-options="{
|
||||
defaultHidden: ['remark', 'description']
|
||||
}"
|
||||
/>
|
||||
```
|
||||
|
||||
### Q: 固定列会自动隐藏吗?
|
||||
|
||||
不会。使用 `fixed="left"` 或 `fixed="right"` 的列会自动标记为不可隐藏。
|
||||
|
||||
## 完整示例
|
||||
|
||||
查看 `src/views/stuwork/classroomhygienemonthly/index.vue` 了解完整的使用示例。
|
||||
|
||||
Reference in New Issue
Block a user