需求描述
当 table 内容过多的时候,页面上滑滚动,表头的信息也会随着被遮挡,无法将表头信息和表格内容对应起来,需要进行表头吸顶
开始编码💪
环境:vue2.6+、element UI
step1: 给el-table__header-wrapper
加上样式
//style/sticky-table-header.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);
}
.el-table__fixed, .el-table__fixed-right{
overflow: visible;
z-index: var(--stick-zIndex);
.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;
}
}
.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;
}
}
&.el-table--border::after{
z-index: var(--stick-zIndex);
}
}
.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);
}
step2: 注册指令 directives/sticky-header.js
import '@/styles/sticky-table-header.scss'
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`)
}
}
step3: main.js 引入
import StickyTableHeader from './directives/sticky-header'
Vue.directive('sticky-table-header', StickyTableHeader)
step4: table.vue
<template>
<div class="wrapper">
<h3>纯CSS表格吸顶</h3>
<el-radio-group v-model="mode" aria-hidden="true" class="options">
<el-radio label="normal">正常模式</el-radio>
<el-radio label="fixedLeft">固定左边列</el-radio>
<el-radio label="fixedRight">固定右边列</el-radio>
<el-radio label="fixedLeftRight">固定左右列</el-radio>
</el-radio-group>
<el-table
v-sticky-table-header="0"
border
:data="tableData"
>
<el-table-column label="日期" prop="date" min-width="150" :fixed="fixedLeft" />
<el-table-column label="姓名" prop="name" width="120" />
<el-table-column label="省份" prop="province" width="120" />
<el-table-column label="市区" prop="city" width="120" />
<el-table-column label="地址" prop="address" width="300" />
<el-table-column label="邮编" prop="zip" min-width="120" :fixed="fixedRight" />
</el-table>
</div>
</template>
<script>
export default {
name: 'CSSFixedTopTable',
components: {},
data() {
const tableData = new Array(100).fill(0).map((_, index) => {
return {
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: `上海市普陀区金沙江路 ${1 + index} 弄`,
zip: 2000001 + index
}
})
return {
tableData,
mode: 'normal'
}
},
computed: {
fixedLeft() {
return /left/i.test(this.mode) ? 'left' : null
},
fixedRight() {
return /right/i.test(this.mode) ? 'right' : null
}
},
methods: {}
}
</script>
<style lang="scss" scoped>
.wrapper {
width: 800px;
margin: 0 auto;
.options {
width: 100%;
margin: 30px 0;
text-align: left;
}
}
</style>
❗️❗️❗️父元素不要有 overflow: hidden;会失效
step5: 效果呈现🤩