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 /** 手动配置的列(如果提供了 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([]) // 列排序 const columnOrder = ref([]) // 列配置(手动配置或从表格提取) 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 } }