Files
school-developer/src/composables/useTableColumnControl.ts
2026-01-22 13:38:10 +08:00

161 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ref, computed, onMounted, nextTick, type Ref } from 'vue'
import { useRoute } from 'vue-router'
import type { TableInstance } from 'element-plus'
export interface ColumnConfig {
prop?: string
label: string
fixed?: boolean | 'left' | 'right'
alwaysShow?: boolean
[key: string]: any
}
/**
* 表格列控制通用 Composable
* 简化 TableColumnControl 组件的使用
*
* @param options 配置选项
* @returns 返回列控制相关的响应式数据和方法
*/
export function useTableColumnControl(options?: {
/** 表格 ref用于自动提取列配置 */
tableRef?: Ref<TableInstance | undefined>
/** 手动配置的列(如果提供了 tableRef 则忽略) */
columns?: ColumnConfig[]
/** localStorage 存储的 key可选默认根据路由自动生成 */
storageKey?: string
/** 默认显示的列prop 或 label 数组) */
defaultVisible?: string[]
/** 始终显示的列prop 或 label 数组) */
alwaysShow?: string[]
}) {
const route = useRoute()
// 根据路由自动生成 storageKey
const getStorageKey = (suffix: string = ''): string => {
if (options?.storageKey) {
return options.storageKey + (suffix ? `-${suffix}` : '')
}
const routePath = route.path.replace(/^\//, '').replace(/\//g, '-')
return `table-columns-${routePath}${suffix ? `-${suffix}` : ''}`
}
// 可见列
const visibleColumns = ref<string[]>([])
// 列排序
const columnOrder = ref<string[]>([])
// 列配置(手动配置或从表格提取)
const tableColumns = computed(() => {
return options?.columns || []
})
// 加载保存的配置
const loadSavedConfig = () => {
const storageKey = getStorageKey()
const saved = localStorage.getItem(storageKey)
if (saved) {
try {
const savedColumns = JSON.parse(saved)
const validColumns = tableColumns.value
.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 if (options?.defaultVisible && options.defaultVisible.length > 0) {
visibleColumns.value = options.defaultVisible
} else {
visibleColumns.value = validColumns
}
} catch (e) {
console.error('解析列配置失败:', e)
visibleColumns.value = options?.defaultVisible || tableColumns.value
.filter(col => !col.alwaysShow && !col.fixed)
.map(col => col.prop || col.label)
}
} else {
visibleColumns.value = options?.defaultVisible || tableColumns.value
.filter(col => !col.alwaysShow && !col.fixed)
.map(col => col.prop || col.label)
}
// 加载列排序配置
const orderKey = getStorageKey('order')
const savedOrder = localStorage.getItem(orderKey)
if (savedOrder) {
try {
const parsedOrder = JSON.parse(savedOrder)
const validColumns = tableColumns.value
.filter(col => !col.alwaysShow && !col.fixed)
.map(col => col.prop || col.label)
columnOrder.value = parsedOrder.filter((key: string) => validColumns.includes(key))
// 添加新列到排序列表末尾
validColumns.forEach(key => {
if (!columnOrder.value.includes(key)) {
columnOrder.value.push(key)
}
})
} catch (e) {
console.error('解析列排序失败:', e)
columnOrder.value = tableColumns.value
.filter(col => !col.alwaysShow && !col.fixed)
.map(col => col.prop || col.label)
}
} else {
columnOrder.value = tableColumns.value
.filter(col => !col.alwaysShow && !col.fixed)
.map(col => col.prop || col.label)
}
}
// 保存列配置
const saveColumnConfig = (columns: string[]) => {
visibleColumns.value = columns
const storageKey = getStorageKey()
const selectableColumns = columns.filter(col => {
const column = tableColumns.value.find(c => (c.prop || c.label) === col)
return column && !column.alwaysShow && !column.fixed
})
localStorage.setItem(storageKey, JSON.stringify(selectableColumns))
}
// 保存列排序
const saveColumnOrder = (order: string[]) => {
columnOrder.value = order
const orderKey = getStorageKey('order')
localStorage.setItem(orderKey, JSON.stringify(order))
}
// 检查列是否可见
const checkColumnVisible = (prop: string): boolean => {
if (visibleColumns.value.length === 0) {
return true
}
return visibleColumns.value.includes(prop)
}
// 初始化
onMounted(() => {
nextTick(() => {
loadSavedConfig()
})
})
return {
visibleColumns,
columnOrder,
tableColumns,
checkColumnVisible,
saveColumnConfig,
saveColumnOrder,
loadSavedConfig,
getStorageKey
}
}