回顾🤔️
去年我在掘金post了一篇文章《elementUI Table组件实现表头吸顶效果》,今年我在空闲的时间想了一下能不能只通过修改CSS来实现吸顶,所以有了这一篇文章。
回顾一下 element 表格吸顶遇到的一些难题,主要是当表格有fixed列的时候,fixed列其实也是一个表格,且是absolute定位的。如图所示,fixed节点和正常的表头的节点在同一个层级。现在要考虑的是如何不改变dom结构不添加js的情况下实现比较好效果的吸顶。
开始编码💪
环境:vue 2.6+
首先,表头还是要做样式的吸顶,也就是el-table_header-wrapper
这个节点要做吸顶的样式。这个还是比较简单的。由于吸顶的高度我们想要动态指定,所有我们定义一个v-sticky-table-header
的指令,指令的值是吸顶的高度值。另外,因为主要是对样式的调整,不想对表头的节点操作太多,所以吸顶高度的变量主要会用CSS变量实现。具体代码如下:
js
export default {
bind(el, binding) {
el.setAttribute('is-sticky', true)
updateStickyTop(el, binding)
},
update(el, binding) {
updateStickyTop(el, binding)
}
}
const updateStickyTop = (el, binding) => {
const { value, oldValue } = binding
if (value === oldValue) return
const top = Number(value)
if (!isNaN(top)) {
el.style.setProperty('--sticky-top', `${top}px`)
}
}
当使用指令的时候,修改顶层节点,包括增加is-sticky
属性以及style增加CSS变量--sticky-top
,使用scss样式如下:
scss
.el-table[is-sticky] {
overflow: initial;
--sticky-top: 0px;
--stick-zIndex: 5;
.el-table__header-wrapper{
position: sticky;
top: var(--sticky-top);
z-index: var(--stick-zIndex);
}
}
- 完成了简单表头的样式吸顶之后,开始考虑fixed列表格的吸顶。由于fixed节点其实也是一个比较完整的 headerTable + bodyTable 的组合,考虑一下让headerTable节点进行单独的吸顶。新增样式如下:(为了可以吸顶父节点
overflow: visible;
,子节点控制宽度overflow:hidden
,headerTable节点sticky
定位)
scss
.el-table__fixed, .el-table__fixed-right{
overflow: visible;
.el-table__fixed-header-wrapper {
position: sticky;
top: var(--sticky-top);
width: 100%;
overflow: hidden;
z-index: var(--stick-zIndex);
}
.el-table__fixed-body-wrapper {
width: 100%;
overflow: hidden;
}
}
效果如下图,右侧fixed列可以看到表头和表体的内容都消失不见了,排查到原因是右侧这里的fixed列由于加了is-hidden
样式所以内容看不见。去掉is-hidden
里面visibility:hidden;
的样式就能看到内容,但是显示的是日期也就是表格第一列的内容。
- 显示最后一列"邮编"的表头和内容。使用
flex
布局,优先显示右边的内容。
scss
.el-table__fixed-right {
.el-table__fixed-header-wrapper {
display: flex;
justify-content: flex-end;
}
.el-table__fixed-body-wrapper {
display: flex;
justify-content: flex-end;
}
}
4. 调整fixed列box-shadow
样式
scss
.el-table__fixed {
--box-shadow: 10px 0 10px -10px rgba(0, 0, 0, 0.12);
}
.el-table__fixed-right {
--box-shadow: -10px 0 10px -10px rgba(0, 0, 0, 0.12);
}
.el-table__fixed, .el-table__fixed-right {
box-shadow: var(--box-shadow);
}
最后呈现结果🤩
在线地址 🔗
源码地址:👇
v-sticky-table-header指令
table 样式