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 官方为什么没有案例,也可能是我没注意到。
  • 为什么不发博客,是因为自己很渺小,一直觉得技术也就那样,没必要发公共博文。
  • 今天发博客,是因为觉得这个 问题 确实没有好的解法,自己发现了,似乎有必要发。
  • 最后,在技术的道路,架构与逻辑是必须较真的。但是对人对讨论,实则没必要。
相关推荐
烬羽5 小时前
后端返回的 JSON 字符串,浏览器怎么"看懂"的?——Ajax 全链路拆解
javascript
半个落月6 小时前
一个新手用 Bun + Axios 调通 DeepSeek API 的实践记录
javascript
不好听6136 小时前
深入理解链表:线性数据结构的另一面
javascript·数据结构
林希_Rachel_傻希希6 小时前
学React治好了我的焦虑症,1小时速通React 前20分钟。
前端·javascript·面试
小林ixn6 小时前
从 Ajax 到异步编程:JSON 序列化、Event Loop 与 XHR 请求完全解析
javascript
丷丩7 小时前
MapLibre GL JS第47课:添加动画图标
javascript·gis·动画·mapbox·maplibre
独泪了无痕7 小时前
Vue3中防御XSS攻击的“特效药”-DOMPurify
前端·vue.js·安全
快乐的哈士奇7 小时前
【Next.js实战①】Gmail API 按柜号检索邮件:OAuth 双 Cookie 与搜索 Fallback
开发语言·javascript·ecmascript
云水一下7 小时前
Vue.js从零到精通系列(五):全局状态管理——Pinia 核心与实践
前端·javascript·vue.js
kmblack18 小时前
javascript计算年龄
开发语言·javascript·ecmascript