(几乎)完美实现 el
- 作者: 五速梦信息网
- 时间: 2026年03月05日 13:17
背景
Element UI 是 PC 端比较流行的 Vue.js UI 框架,它的组件库基本能满足大部分常见的业务需求。但有时候会有一些定制性比较高的需求,组件本身可能没办法满足。最近在项目里就碰到了。
el-tableel-table-columnel-table
el-table-column
技术方案
于是想到了动态计算内容宽度的方案。网上也有人提过这个思路,做法是根据内容字符数来计算宽度。这种方法有几个局限:
- 内容必须是文本
- 不同字符宽度不一,结算结果不够准确
- 需要在渲染前操作数据,不利于解耦
我采用了另一种思路,还是动态计算内容宽度,但是根据实际渲染后的 DOM 元素宽度,这样就能解决上面三个问题。
el-tabletablecolgroupcolnametdclass
具体实现
.cellwhite-space: nowrap; overflow: auto;display: inline-block;.cellscrollWidth
function adjustColumnWidth(table) {
const colgroup = table.querySelector("colgroup");
const colDefs = [...colgroup.querySelectorAll("col")];
colDefs.forEach((col) => {
const clsName = col.getAttribute("name");
const cells = [
...table.querySelectorAll(`td.${clsName}`),
...table.querySelectorAll(`th.${clsName}`),
];
// 忽略加了"leave-alone"类的列
if (cells[0]?.classList?.contains?.("leave-alone")) {
return;
}
const widthList = cells.map((el) => {
return el.querySelector(".cell")?.scrollWidth || 0;
});
const max = Math.max(...widthList);
const padding = 32;
table.querySelectorAll(`col[name=${clsName}]`).forEach((el) => {
el.setAttribute("width", max + padding);
});
});
}
中间的探索过程比较繁琐,但最终的代码实现却非常简洁。在什么时候触发列宽计算呢?自然是组件渲染完成后。为了方便重用,我采用了 Vue 自定义指令的方式。
Vue.directive("fit-columns", {
update() {},
bind() {},
inserted(el) {
setTimeout(() => {
adjustColumnWidth(el);
}, 300);
},
componentUpdated(el) {
el.classList.add("r-table");
setTimeout(() => {
adjustColumnWidth(el);
}, 300);
},
unbind() {},
});
v-fit-columns
npm install v-fit-columns --save
引入:
import Vue from 'vue';
import Plugin from 'v-fit-columns';
Vue.use(Plugin);
使用:
<el-table v-fit-columns>
<el-table-column label="No." type="index" class-name="leave-alone"></el-table-column>
<el-table-column label="Name" prop="name"></el-table-column>
<el-table-column label="Age" prop="age"></el-table-column>
</el-table>
源码仓库在这:https://github.com/kaysonli/v-fit-columns ,欢迎各位不吝赐教和 Star!
总结
这个方案多少有点 Hack 的意味,只顾实现需求,可能在其他方面还有点瑕疵,比如渲染完后会稍微闪一下(因为要重新调整宽度,会出现 reflow)。不过从最终实现的效果来看,还算令人满意,至少产品经理提着他的两米大刀走了……他可是为了这个效果,蹲守在我电脑前半个下午,非要我实现不可!在手摸手的胁迫下,总算完事交差了……
看在这个logo的份上,不来关注下吗?

相关文章
-
(委托事件处理)关于多线程执行显示进度条的实例(转)&&线程间操作无效: 从不是创建控件“rtxtEntryNO”的线程访问它。
(委托事件处理)关于多线程执行显示进度条的实例(转)&&线程间操作无效: 从不是创建控件“rtxtEntryNO”的线程访问它。
- 互联网
- 2026年03月05日
-
(效果一)js实现上拉加载
(效果一)js实现上拉加载
- 互联网
- 2026年03月05日
-
(学习网址)Python 自动化测试
(学习网址)Python 自动化测试
- 互联网
- 2026年03月05日
-
(翻译)FIFO In Hardware
(翻译)FIFO In Hardware
- 互联网
- 2026年03月05日
-
(八)Struts2中的参数封装
(八)Struts2中的参数封装
- 互联网
- 2026年03月05日
-
(ssh整合web导出excel)在ssh框架中使用poi正确导出具有比较高级固定格式的excel 整体过程,查询导出前后台下载
(ssh整合web导出excel)在ssh框架中使用poi正确导出具有比较高级固定格式的excel 整体过程,查询导出前后台下载
- 互联网
- 2026年03月05日


