云计算百科
云计算领域专业知识百科平台

element-plus table组件 封装列隐藏功能,并非 v-if 或 v-for,通过tableRef 与样式控制

封装 Element Plus Table 列隐藏功能

使用 tableRef 和样式控制实现列隐藏

通过操作表格的 DOM 结构和样式,可以实现列的动态隐藏与显示。这种方法不依赖 v-if 或 v-for,而是直接控制列的可见性。

<template>
<el-table ref="tableRef" :data="tableData">
<el-table-column prop="date" label="日期" />
<el-table-column prop="name" label="姓名" />
<el-table-column prop="address" label="地址" />
</el-table>
<el-button @click="toggleColumn('name')">切换姓名列</el-button>
</template>

<script setup>
import { ref } from 'vue';

const tableRef = ref();
const tableData = [
{ date: '2023-01-01', name: '张三', address: '北京' },
{ date: '2023-01-02', name: '李四', address: '上海' }
];

const toggleColumn = (prop) => {
if (!tableRef.value) return;

const table = tableRef.value.$el;
const header = table.querySelector('.el-table__header-wrapper');
const body = table.querySelector('.el-table__body-wrapper');

// 获取所有列
const headerCols = header.querySelectorAll('th');
const bodyCols = body.querySelectorAll('tr td');

// 查找目标列索引
let colIndex = -1;
headerCols.forEach((th, index) => {
if (th.getAttribute('data-property') === prop) {
colIndex = index;
}
});

if (colIndex === -1) return;

// 切换列的显示状态
headerCols[colIndex].style.display =
headerCols[colIndex].style.display === 'none' ? '' : 'none';

bodyCols.forEach((td, index) => {
if (index % headerCols.length === colIndex) {
td.style.display =
td.style.display === 'none' ? '' : 'none';
}
});
};
</script>

封装为可复用的 Hook

可以将列隐藏逻辑封装为可复用的 Composition API Hook:

// useTableColumnToggle.js
import { ref } from 'vue';

export function useTableColumnToggle(tableRef) {
const toggleColumn = (prop) => {
if (!tableRef.value) return;

const table = tableRef.value.$el;
const header = table.querySelector('.el-table__header-wrapper');
const body = table.querySelector('.el-table__body-wrapper');

const headerCols = header.querySelectorAll('th');
const bodyCols = body.querySelectorAll('tr td');

let colIndex = -1;
headerCols.forEach((th, index) => {
if (th.getAttribute('data-property') === prop) {
colIndex = index;
}
});

if (colIndex === -1) return;

const isHidden = headerCols[colIndex].style.display === 'none';
const newDisplay = isHidden ? '' : 'none';

headerCols[colIndex].style.display = newDisplay;
bodyCols.forEach((td, index) => {
if (index % headerCols.length === colIndex) {
td.style.display = newDisplay;
}
});
};

return { toggleColumn };
}

使用 Hook 的示例

<template>
<el-table ref="tableRef" :data="tableData">
<el-table-column prop="date" label="日期" />
<el-table-column prop="name" label="姓名" />
<el-table-column prop="address" label="地址" />
</el-table>
<el-button @click="toggleNameColumn">切换姓名列</el-button>
</template>

<script setup>
import { ref } from 'vue';
import { useTableColumnToggle } from './useTableColumnToggle';

const tableRef = ref();
const tableData = [
{ date: '2023-01-01', name: '张三', address: '北京' },
{ date: '2023-01-02', name: '李四', address: '上海' }
];

const { toggleColumn } = useTableColumnToggle(tableRef);
const toggleNameColumn = () => toggleColumn('name');
</script>

注意事项
  • 这种方法直接操作 DOM,可能在某些极端情况下不如 Vue 的响应式系统稳定
  • 需要确保列的 prop 属性与数据中的字段名一致
  • 对于复杂的表格结构(如固定列、多级表头),可能需要调整选择器逻辑
  • 性能上优于 v-if,因为不会触发组件的销毁和重建
  • 扩展功能

    可以进一步扩展 Hook 以支持批量操作:

    // 在 useTableColumnToggle.js 中添加
    const toggleColumns = (props) => {
    props.forEach(prop => toggleColumn(prop));
    };

    const hideColumns = (props) => {
    props.forEach(prop => {
    if (!tableRef.value) return;
    // 类似 toggleColumn 逻辑,但强制隐藏
    });
    };

    const showColumns = (props) => {
    props.forEach(prop => {
    if (!tableRef.value) return;
    // 类似 toggleColumn 逻辑,但强制显示
    });
    };

    return { toggleColumn, toggleColumns, hideColumns, showColumns };

    avg.163.com/topic/detail/8834434
    avg.163.com/topic/detail/8834458
    avg.163.com/topic/detail/8834461
    avg.163.com/topic/detail/8834325
    avg.163.com/topic/detail/8834014
    avg.163.com/topic/detail/8834362
    avg.163.com/topic/detail/8834356
    avg.163.com/topic/detail/8834456
    avg.163.com/topic/detail/8834455
    avg.163.com/topic/detail/8834381
    avg.163.com/topic/detail/8834353
    avg.163.com/topic/detail/8834550
    avg.163.com/topic/detail/8834516
    avg.163.com/topic/detail/8834320
    avg.163.com/topic/detail/8834581
    avg.163.com/topic/detail/8834382
    avg.163.com/topic/detail/8834493
    avg.163.com/topic/detail/8834551
    avg.163.com/topic/detail/8834481
    avg.163.com/topic/detail/8834518
    avg.163.com/topic/detail/8834515
    avg.163.com/topic/detail/8834498
    avg.163.com/topic/detail/8834041
    avg.163.com/topic/detail/8834525
    avg.163.com/topic/detail/8834494
    avg.163.com/topic/detail/8834386
    avg.163.com/topic/detail/8834490
    avg.163.com/topic/detail/8834420
    avg.163.com/topic/detail/8834519
    avg.163.com/topic/detail/8834389
    avg.163.com/topic/detail/8834542
    avg.163.com/topic/detail/8834354
    avg.163.com/topic/detail/8834421
    avg.163.com/topic/detail/8834609
    avg.163.com/topic/detail/8834380
    avg.163.com/topic/detail/8834520
    avg.163.com/topic/detail/8834578
    avg.163.com/topic/detail/8834546
    avg.163.com/topic/detail/8834611
    avg.163.com/topic/detail/8834543
    avg.163.com/topic/detail/8834083
    avg.163.com/topic/detail/8834572
    avg.163.com/topic/detail/8834553
    avg.163.com/topic/detail/8834521
    avg.163.com/topic/detail/8834426
    avg.163.com/topic/detail/8834580
    avg.163.com/topic/detail/8834480
    avg.163.com/topic/detail/8834548
    avg.163.com/topic/detail/8834422
    avg.163.com/topic/detail/8834510
    avg.163.com/topic/detail/8834448
    avg.163.com/topic/detail/8834571
    avg.163.com/topic/detail/8834641
    avg.163.com/topic/detail/8834419
    avg.163.com/topic/detail/8834668
    avg.163.com/topic/detail/8834544
    avg.163.com/topic/detail/8834605
    avg.163.com/topic/detail/8834642
    avg.163.com/topic/detail/8834636
    avg.163.com/topic/detail/8834115
    avg.163.com/topic/detail/8834606
    avg.163.com/topic/detail/8834549
    avg.163.com/topic/detail/8834637
    avg.163.com/topic/detail/8834452
    avg.163.com/topic/detail/8834612
    avg.163.com/topic/detail/8834573
    avg.163.com/topic/detail/8834643
    avg.163.com/topic/detail/8834450
    avg.163.com/topic/detail/8834483
    avg.163.com/topic/detail/8834539
    avg.163.com/topic/detail/8834603
    avg.163.com/topic/detail/8834485
    avg.163.com/topic/detail/8834696
    avg.163.com/topic/detail/8834447
    avg.163.com/topic/detail/8834576
    avg.163.com/topic/detail/8834666
    avg.163.com/topic/detail/8834608
    avg.163.com/topic/detail/8834665
    avg.163.com/topic/detail/8834142
    avg.163.com/topic/detail/8834694
    avg.163.com/topic/detail/8832562
    avg.163.com/topic/detail/8834579
    avg.163.com/topic/detail/8834664
    avg.163.com/topic/detail/8834488
    avg.163.com/topic/detail/8834604
    avg.163.com/topic/detail/8834517
    avg.163.com/topic/detail/8834511
    avg.163.com/topic/detail/8834670
    avg.163.com/topic/detail/8834631
    avg.163.com/topic/detail/8834567
    avg.163.com/topic/detail/8834513
    avg.163.com/topic/detail/8834732
    avg.163.com/topic/detail/8834478
    avg.163.com/topic/detail/8834538
    avg.163.com/topic/detail/8834695
    avg.163.com/topic/detail/8834735
    avg.163.com/topic/detail/8834633
    avg.163.com/topic/detail/8834168
    avg.163.com/topic/detail/8833802
    avg.163.com/topic/detail/8834730
    avg.163.com/topic/detail/8834203
    avg.163.com/topic/detail/8834607
    avg.163.com/topic/detail/8834690
    avg.163.com/topic/detail/8834635
    avg.163.com/topic/detail/8834731
    avg.163.com/topic/detail/8834545
    avg.163.com/topic/detail/8834540
    avg.163.com/topic/detail/8834697
    avg.163.com/topic/detail/8834656
    avg.163.com/topic/detail/8834753
    avg.163.com/topic/detail/8834599
    avg.163.com/topic/detail/8834509
    avg.163.com/topic/detail/8834569
    avg.163.com/topic/detail/8834566
    avg.163.com/topic/detail/8834755
    avg.163.com/topic/detail/8834657
    avg.163.com/topic/detail/8833918
    avg.163.com/topic/detail/8834759
    avg.163.com/topic/detail/8834235
    avg.163.com/topic/detail/8834634
    avg.163.com/topic/detail/8834786
    avg.163.com/topic/detail/8834659
    avg.163.com/topic/detail/8834752
    avg.163.com/topic/detail/8834574
    avg.163.com/topic/detail/8834568
    avg.163.com/topic/detail/8834610
    avg.163.com/topic/detail/8834733
    avg.163.com/topic/detail/8834788
    avg.163.com/topic/detail/8834685
    avg.163.com/topic/detail/8834758
    avg.163.com/topic/detail/8834626
    avg.163.com/topic/detail/8834600
    avg.163.com/topic/detail/8834598
    avg.163.com/topic/detail/8834628
    avg.163.com/topic/detail/8834688
    avg.163.com/topic/detail/8834789
    avg.163.com/topic/detail/8833946
    avg.163.com/topic/detail/8833975
    avg.163.com/topic/detail/8834662
    avg.163.com/topic/detail/8834261
    avg.163.com/topic/detail/8834693
    avg.163.com/topic/detail/8834783
    avg.163.com/topic/detail/8834727
    avg.163.com/topic/detail/8834601
    avg.163.com/topic/detail/8834687
    avg.163.com/topic/detail/8834790
    avg.163.com/topic/detail/8834723
    avg.163.com/topic/detail/8834627
    avg.163.com/topic/detail/8834638
    avg.163.com/topic/detail/8834654
    avg.163.com/topic/detail/8834722
    avg.163.com/topic/detail/8834760
    avg.163.com/topic/detail/8834013
    avg.163.com/topic/detail/8834684
    avg.163.com/topic/detail/8834655
    avg.163.com/topic/detail/8834080
    avg.163.com/topic/detail/8834787
    avg.163.com/topic/detail/8834629
    avg.163.com/topic/detail/8834661
    avg.163.com/topic/detail/8834718
    avg.163.com/topic/detail/8834728
    avg.163.com/topic/detail/8834297
    avg.163.com/topic/detail/8834747
    avg.163.com/topic/detail/8834658
    avg.163.com/topic/detail/8834686
    avg.163.com/topic/detail/8834785
    avg.163.com/topic/detail/8834757
    avg.163.com/topic/detail/8834683
    avg.163.com/topic/detail/8834327
    avg.163.com/topic/detail/8834113
    avg.163.com/topic/detail/8834781
    avg.163.com/topic/detail/8834744
    avg.163.com/topic/detail/8834751
    avg.163.com/topic/detail/8834726
    avg.163.com/topic/detail/8834169
    avg.163.com/topic/detail/8834660
    avg.163.com/topic/detail/8834360
    avg.163.com/topic/detail/8834778
    avg.163.com/topic/detail/8834201
    avg.163.com/topic/detail/8834689
    avg.163.com/topic/detail/8834750
    avg.163.com/topic/detail/8834777
    avg.163.com/topic/detail/8834384
    avg.163.com/topic/detail/8834724
    avg.163.com/topic/detail/8834734
    avg.163.com/topic/detail/8834423
    avg.163.com/topic/detail/8834720
    avg.163.com/topic/detail/8834749
    avg.163.com/topic/detail/8834754
    avg.163.com/topic/detail/8834449
    avg.163.com/topic/detail/8834746
    avg.163.com/topic/detail/8834233
    avg.163.com/topic/detail/8834784
    avg.163.com/topic/detail/8834776
    avg.163.com/topic/detail/8834779
    avg.163.com/topic/detail/8834260
    avg.163.com/topic/detail/8834775
    avg.163.com/topic/detail/8834804
    avg.163.com/topic/detail/8834479
    avg.163.com/topic/detail/8834296
    avg.163.com/topic/detail/8834514
    avg.163.com/topic/detail/8834319
    avg.163.com/topic/detail/8834541
    avg.163.com/topic/detail/8834352
    avg.163.com/topic/detail/8834570
    avg.163.com/topic/detail/8834418
    avg.163.com/topic/detail/8834630
    avg.163.com/topic/detail/8834446
    avg.163.com/topic/detail/8834663
    avg.163.com/topic/detail/8834477
    avg.163.com/topic/detail/8834691
    avg.163.com/topic/detail/8834536
    avg.163.com/topic/detail/8834729
    avg.163.com/topic/detail/8834565
    avg.163.com/topic/detail/8834748
    avg.163.com/topic/detail/8834596
    avg.163.com/topic/detail/8834782
    avg.163.com/topic/detail/8834625
    avg.163.com/topic/detail/8834652
    avg.163.com/topic/detail/8834681
    avg.163.com/topic/detail/8834714
    avg.163.com/topic/detail/8834743
    avg.163.com/topic/detail/8834774

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » element-plus table组件 封装列隐藏功能,并非 v-if 或 v-for,通过tableRef 与样式控制
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!