# 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` 了解完整的使用示例。

