Files
school-developer/COLUMN_VISIBILITY_SOLUTIONS.md
guochunsi 9e583c3c30 a
2026-01-06 16:39:57 +08:00

164 lines
3.8 KiB
Markdown
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.

# 列显示/隐藏方案对比
## 方案1TableColumn 包装组件 ⭐推荐
### 优点
- ✅ 使用简单,只需替换组件名
- ✅ 完全兼容 `el-table-column` 的所有属性和插槽
- ✅ 代码清晰,易于维护
- ✅ 无需修改现有代码结构
### 缺点
- ❌ 需要创建一个新组件
- ❌ 需要在使用的地方 provide `isColumnVisible` 函数
### 使用示例
```vue
<template>
<el-table ref="tableRef">
<TableColumnProvider :is-column-visible="isColumnVisible">
<!-- 替换 el-table-column TableColumn移除 v-if -->
<TableColumn prop="tied" label="是否退休" width="100" align="center">
<template #default="scope">
<StatusTag :value="scope.row.tied" :options="YES_OR_NO" />
</template>
</TableColumn>
<TableColumn prop="nameNo" label="姓名/工号" min-width="150" align="center" fixed>
<template #default="scope">
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
</template>
</TableColumn>
</TableColumnProvider>
</el-table>
</template>
<script setup>
import TableColumnProvider from '/@/components/TableColumn/Provider.vue'
import TableColumn from '/@/components/TableColumn/index.vue'
const isColumnVisible = (propOrLabel) => {
return tableColumnControlRef.value?.isColumnVisible?.(propOrLabel) ?? true
}
</script>
```
---
## 方案2自定义指令 v-column-visible
### 优点
- ✅ 可以保留 `el-table-column`
- ✅ 使用相对简单
### 缺点
- ❌ 仍然需要在每个列上添加指令
- ❌ 实现较复杂,需要操作 DOM
- ❌ 可能不够优雅
### 使用示例
```vue
<template>
<el-table>
<el-table-column
v-column-visible="'tied'"
prop="tied"
label="是否退休"
width="100"
/>
</el-table>
</template>
```
---
## 方案3使用 computed 动态生成列配置
### 优点
- ✅ 最彻底,完全控制列的渲染
- ✅ 性能最好(只渲染可见的列)
### 缺点
- ❌ 需要重构现有代码,改动较大
- ❌ 需要将列配置抽离出来
- ❌ 插槽处理较复杂
### 使用示例
```vue
<template>
<el-table>
<component
v-for="col in visibleColumns"
:is="col.component"
v-bind="col.props"
>
<template v-if="col.slots" #[slotName]="slotProps" v-for="(slot, slotName) in col.slots">
<component :is="slot" v-bind="slotProps" />
</template>
</component>
</el-table>
</template>
<script setup>
const columns = [
{ prop: 'tied', label: '是否退休', component: 'el-table-column', slots: { default: StatusTag } },
// ...
]
const visibleColumns = computed(() => {
return columns.filter(col => isColumnVisible(col.prop || col.label))
})
</script>
```
---
## 方案4在 el-table 层面使用 provide + 自动处理
### 优点
- ✅ 在表格层面统一处理
- ✅ 子组件自动继承
### 缺点
- ❌ 实现最复杂
- ❌ 需要修改 Element Plus 的渲染逻辑
- ❌ 可能影响性能
---
## 推荐方案
**推荐使用方案1TableColumn 包装组件)**,因为:
1. 使用最简单,只需替换组件名
2. 完全兼容现有代码
3. 易于维护和理解
4. 性能良好
## 迁移步骤方案1
1. 导入组件:
```vue
import TableColumnProvider from '/@/components/TableColumn/Provider.vue'
import TableColumn from '/@/components/TableColumn/index.vue'
```
2.`TableColumnProvider` 包裹所有列,并传入 `isColumnVisible`
```vue
<TableColumnProvider :is-column-visible="isColumnVisible">
<!-- 所有列 -->
</TableColumnProvider>
```
3. 将所有 `el-table-column` 替换为 `TableColumn`,并移除 `v-if`
```vue
<!-- 之前 -->
<el-table-column v-if="isColumnVisible('tied')" prop="tied" label="是否退休" />
<!-- 之后 -->
<TableColumn prop="tied" label="是否退休" />
```