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 官方为什么没有案例,也可能是我没注意到。
  • 为什么不发博客,是因为自己很渺小,一直觉得技术也就那样,没必要发公共博文。
  • 今天发博客,是因为觉得这个 问题 确实没有好的解法,自己发现了,似乎有必要发。
  • 最后,在技术的道路,架构与逻辑是必须较真的。但是对人对讨论,实则没必要。
相关推荐
放下华子我只抽RuiKe513 小时前
React 从入门到生产(四):自定义 Hook
前端·javascript·人工智能·深度学习·react.js·自然语言处理·前端框架
XinZong14 小时前
OpenClaw 实现双重心跳(Heartbeat)+ clawreach虾聊项目实现
javascript
还有多久拿退休金15 小时前
一张栈的图,治好你面试答不出 script 阻塞的病
前端·javascript
zithern_juejin16 小时前
原型与原型链
javascript
还有多久拿退休金17 小时前
我用 Three.js 造了个 3D 漫步世界,角色走路像喝醉了——以及我是怎么修好的
前端·vue.js
LJA6484417 小时前
为什么 AI 时代更需要配置化组件库
vue.js
008爬虫实战录18 小时前
【码上爬】 题十二:如来神掌 困难, JSVMP加密,使用代理补环境
前端·javascript·node.js
threelab18 小时前
Three.js 数学函数着色器 | 三维可视化 / AI 提示词
javascript·人工智能·着色器
ZC跨境爬虫19 小时前
跟着 MDN 学CSS day_3:(为一个传记页面添加样式)
前端·javascript·css·ui·音视频·html5
夜雪闻竹19 小时前
sql.js WASM 实战:浏览器里跑 SQLite
javascript·sql·wasm