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

1、背景

2026年1月6日 csdn 好久没上传文章了,今天开发项目遇到个表格按需隐藏列的功能,调研了下网上的案例,大概就下面几种解法:

  1. v-if 法 <el-table-column> 挨个加判断(繁琐)
  2. v-for 法 <el-table-column> 循环层加判断(简单,但是没法适用自定义内容)

2、寻找解法

这里我们做程序开发,力求一劳永逸,符合需求的同时,尽可能找到最优解。这里我找解的过程如下:

  1. <ElTable ... ref="tableRef"/> tableRef 拿到表格组件暴露API
  2. 从暴露API中 找是否有隐藏列的方法(然而没有)
  3. 切换思路2,找到 table.columns 列信息 然后实际一轮测试后,是无法完成列更新的。(这个columns 信息更像是表格更新完的引用,没有双向数据绑定,也不会起到render阶段列更新)
  4. 切换思路3,后面发现 table render的dom元素中 el-table__header 下有 colgroup

对应的el-table__body 下也有 colgroup

  1. 然后直觉导向,我尝试给 __header 和 __body下这2列的 <col>标签 都加上 display:"none"后,发现效果就是我想要到:列被隐藏 并且表格宽度是自适应的

  2. 接下来就是封装一个方法,传 hiddenPropList 并找到对应的 colgroup下col项,进行隐藏即可。

3、具体解

这里我直接贴关键伪代码了(因为本人是TS开发的,代码体量较多我抓核心列)

1、组件开设 hiddenPropList 传参 // 传参如 ['roomCode'] 传入的是 el-table-column 对应的列字段

javascript 复制代码
const props = withDefaults(defineProps<Props>(), {
  hiddenPropList: () => [],
});

2、ElTable 组件需要用到 header-cell-class-name, cell-class-name 两个prop 以及 1个ref

javascript 复制代码
   <ElTable
        ...
        :header-cell-class-name="tableHeaderCellClassName"
        :cell-class-name="tableCellClassName"
        ref="tableRef"
      >

3、对应的方法具体实现 // 下述2方法,主要是基于 hiddenPropList 对单元格进行隐藏,以及核心的colgroup 下 col 的隐藏,当然如果 hiddenPropList 动态变更,表格也会基于传参刷新。

javascript 复制代码
function tableHeaderCellClassName(data: any) {
  const prop = data.column.property;
  const name = data.column.id;
  const table = tableRef.value!!;

  const { context } = table;
  const tableHeaderEle = context.refs.headerWrapper;
  const bodyWrapperEle = context.refs.bodyWrapper;

  const needHidden = props.hiddenPropList.includes(prop);
  const colgroupHeader = tableHeaderEle.querySelector(`[name="${name}"]`);
  const colgroupBody = bodyWrapperEle.querySelector(`[name="${name}"]`);

  if (needHidden) {
    console.log(colgroupHeader, colgroupBody);
    colgroupHeader?.classList.add("hidden");
    colgroupBody?.classList.add("hidden");
    // 直接强行给对应的 colgroup 赋予 hidden
    return "hidden";
  }

  colgroupHeader?.classList.remove("hidden");
  colgroupBody?.classList.remove("hidden");

  return "";
}

function tableCellClassName(data: any) {
  const prop = data.column.property;
  const needHidden = props.hiddenPropList.includes(prop);

  if (needHidden) {
    return "hidden";
  }
  
  return "";
}

4、外部组件使用 就传一个 hidden-prop-list 就可以实现列的自由隐藏了

javascript 复制代码
 <LabRoomManageList
     ....
      :hidden-prop-list="['roomCode']"
    />

4、封装优化

1、上述核心代码已贴,其实重要的是思路,但是目前只是做到了独立业务表格的 列隐藏,站在"封装"的思想来说,还不够。

2、这里面上述2个 tableCellClassName tableHeaderCellClassName,是可以封装给hook的,也就是需要用到的表格组件,比如通过 useTableUtils(tableRef,{ hiddenPropList }) 这种。就可以实现统一管控。

3、还有需求比如类似 表格特定行 无法选中,也是这种思路 比如可以开设 disabledIdList,通过 tableRowClassName 行样式控制做到无法点击。

5、题外话

  • 上一篇CSDN的博客还是停留在 2020-06-02,那年我刚毕业。
  • 目前自己还是专职干前端工作,现在月收入到手还是四位数(之前勉强也有五位数的时候)
  • 可能看到这里的人,我觉得大部分是不依赖AI工作的人,更多是拥抱AI前进的人。
  • 这个table表单列的隐藏,暂不清楚 element 官方为什么没有案例,也可能是我没注意到。
  • 为什么不发博客,是因为自己很渺小,一直觉得技术也就那样,没必要发公共博文。
  • 今天发博客,是因为觉得这个 问题 确实没有好的解法,自己发现了,似乎有必要发。
  • 最后,在技术的道路,架构与逻辑是必须较真的。但是对人对讨论,实则没必要。
相关推荐
Cobyte15 分钟前
3.响应式系统基础:从发布订阅模式的角度理解 Vue2 的数据响应式原理
前端·javascript·vue.js
竹林81819 分钟前
从零到一:在React前端中集成The Graph查询Uniswap V3池数据实战
前端·javascript
军军君0129 分钟前
Three.js基础功能学习十八:智能黑板实现实例五
前端·javascript·vue.js·3d·typescript·前端框架·threejs
Moment31 分钟前
AI全栈入门指南:一文搞清楚NestJs 中的 Controller 和路由
前端·javascript·后端
禅思院31 分钟前
前端架构演进:基于AST的常量模块自动化迁移实践
前端·vue.js·前端框架
程序员马晓博32 分钟前
前端并发治理:从 Token 刷新聊起,一个 Promise 就够了
前端·javascript
许杰小刀32 分钟前
FastAPI + Vue 前后端分离实战:我的项目结构“避坑指南”
前端·vue.js·fastapi
walking9571 小时前
Vue3 日历组件选型指南:五大主流方案深度解析
前端·vue.js·面试
英俊潇洒美少年1 小时前
Vue、React.lazy、React 19 异步组件核心区别
javascript·vue.js·react.js
快乐小土豆~~2 小时前
echarts柱状图的X轴label过长被重叠覆盖
前端·javascript·vue.js·echarts