// 表格header吸顶
const sticky = {
mounted(el: any, binding: any) {
// 获取吸顶状态的偏移量
// 监听滚动事件
let clonedElement: any, header: any
const handleScroll = (e: any) => {
const scrollTop = e.target.scrollTop
const offset = el.offsetTop - 60;
//60为表头高度
header = el.getElementsByClassName('el-table__header-wrapper')[0]
clonedElement = el.getElementsByClassName('el-cloned')[0]
//30为表头高度的一半
if (scrollTop +30> offset) {
if (clonedElement) {
clonedElement.style.display = 'block';
} else {
// 克隆原始元素
clonedElement = header.cloneNode(true);
// 将克隆的元素添加到原始元素后面
header.parentNode.insertBefore(clonedElement, header.nextSibling);
clonedElement.className = 'el-cloned'
clonedElement.style.position = 'fixed';
clonedElement.style.top = `${91}px`;
//91为表头距离浏览器顶部高度
clonedElement.style.zIndex = '9999'; // 自定义吸顶元素的层级
}
} else {
if (clonedElement)
clonedElement.style.display = 'none';
}
if (clonedElement) {
clonedElement.children[0].style.width = header.getBoundingClientRect().width + 'px'; // 设置克隆元素的宽度
}
};
const handleResize = () => {
if (clonedElement) {
clonedElement.children[0].style.width = header.getBoundingClientRect().width + 'px'; // 设置克隆元素的宽度
}
}
el._handleScroll = handleScroll;
el._handleResize = handleResize;
// 绑定滚动事件
window.addEventListener('scroll', handleScroll, true);
// 绑定浏览器宽度改变事件
window.addEventListener('resize', handleResize);
},
beforeUnmount(el:any) {
window.removeEventListener('scroll', el._handleScroll);
window.removeEventListener('resize', el._handleResize);
delete el._handleScroll;
delete el._handleResize;
}
};
export default sticky;
挂载
import sticky from "@/directive/modules/sticky";
// 自定义指令
export default {
install(Vue:any) {
Vue.directive('sticky',sticky)
},
}
element el-table表格使用
<template>
<el-table v-sticky :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
</template>
原生table表格使用
<script setup lang="ts">
import {onMounted, onUnmounted, ref} from "vue";
const elementToTrack = ref();
const w=ref<number>();
const observeWidth = () => {
const element:Element = elementToTrack.value;
const observer = new ResizeObserver((entries) => {
for (let entry of entries) {
w.value = entry.contentRect.width/6;
}
});
observer.observe(element);
};
onMounted(() => {
observeWidth();
});
onUnmounted(() => {
// 在组件销毁前停止观察
const element = elementToTrack.value;
const observer = new ResizeObserver((entries) => {
observer.unobserve(element);
});
});
</script>
<template>
<div v-sticky>
<div class="el-table__header-wrapper" ref="elementToTrack">
<table class="order-table">
<colgroup>
<col :width="w*3">
<col :width="w">
<col :width="w">
<col :width="w">
</colgroup>
<thead>
<tr>
<th>商品名称</th>
<th>买家手机号</th>
<th>订单状态</th>
<th>实付金额</th>
</tr>
</thead>
</table>
</div>
<table>
<colgroup>
<col :width="w*3">
<col :width="w">
<col :width="w">
<col :width="w">
</colgroup>
<tbody v-for="order in list" :key="order.id">
<tr>
<td colspan="3"></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</template>
<style scoped lang="scss">
</style>