vue3实现多个表格同时滚动并固定表头
作者:℘团子এ
说明:这里需分为两种情况来做。第一种亲情况就是没有修改过el-table这个组件的样式;第二种情况就是修改过el-table组件的样式。第一种较为简单就简单略过,这里主要提及第二种做法。
1.需求效果
2.第一种没有修改过el-table这个组件的样式的做法
(1)直接看大佬vue2的做法
element ui 实现多个table同时滚动,横向纵向滚动
代码如下:
<script src="//unpkg.com/vue/dist/vue.js"></script> <script src="//unpkg.com/element-ui@2.15.6/lib/index.js"></script> <div id="app"> <template> <el-table ref="table1" border="10" height="150" :data="tableData" style="width: 800px"> <el-table-column prop="date" label="日期" width="300"> </el-table-column> <el-table-column prop="name" label="姓名" width="300"> </el-table-column> <el-table-column width="300px" prop="address" label="地址"> </el-table-column> <el-table-column width="300px" prop="address" label="地址"> </el-table-column> </el-table> <el-table ref="table2" border="10" height="150" :data="tableData" style="width: 800px"> <el-table-column prop="date" label="日期" width="300"> </el-table-column> <el-table-column prop="name" label="姓名" width="300"> </el-table-column> <el-table-column width="300px" prop="address" label="地址"> </el-table-column> <el-table-column width="300px" prop="address" label="地址"> </el-table-column> </el-table> </template> </div>
var Main = { data() { return { tableData: [{ date: '2016-05-02', name: '王小虎', address: '上海市' }, { date: '2016-05-04', name: '王小虎', address: '上海市' }, { date: '2016-05-04', name: '王小虎', address: '上海市' }, { date: '2016-05-04', name: '王小虎', address: '上海市' }], dom1: null, dom2: null } }, mounted() { this.dom1 = this.$refs.table1.bodyWrapper this.dom2 = this.$refs.table2.bodyWrapper this.listenerScroll() }, methods: { listenerScroll() { this.dom2.addEventListener('scroll', () => { // 横滚 this.dom1.scrollLeft = this.dom2.scrollLeft // 竖滚 this.dom1.scrollTop = this.dom2.scrollTop }) } } } var Ctor = Vue.extend(Main) new Ctor().$mount('#app')
(2)以下是vue3写法(可以直接使用看看效果,没效果的就看第二种方法)
<template> <div> <el-table ref="table1" :data="tableData" style="width: 100%; margin-bottom: 20px" height="200px"> <el-table-column prop="date" label="Date" width="180"></el-table-column> <el-table-column prop="name" label="Name" width="180"></el-table-column> </el-table> <el-table ref="table2" :data="tableData" style="width: 100%" height="200px"> <el-table-column prop="address" label="Address" width="180"></el-table-column> <el-table-column prop="tag" label="Tag" width="180"></el-table-column> </el-table> </div> </template> <script setup> import { ref, onMounted } from 'vue' import { ElTable } from 'element-plus' const table1 = ref(null) const table2 = ref(null) let overElement = "" onMounted(() => { const table1Wrapper = table1.value.$refs.bodyWrapper const table2Wrapper = table2.value.$refs.bodyWrapper console.log("table1Wrapper",table1Wrapper); table1Wrapper.addEventListener('mouseover', () => { overElement = "a" console.log("overElement1",overElement); }) table2Wrapper.addEventListener('mouseover', () => { overElement = "b" console.log("overElement2",overElement); }) table1Wrapper.addEventListener('scroll', () => { console.log("overElement3",overElement); if (overElement === "a") { console.log("overElement4",overElement); table2Wrapper.scrollTop = table1Wrapper.scrollTop } }) table2Wrapper.addEventListener('scroll', () => { console.log("overElement5",overElement); if (overElement === "b") { console.log("overElement6",overElement); table1Wrapper.scrollTop = table2Wrapper.scrollTop } }) }) const tableData = [ { date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', tag: 'Home', }, { date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', tag: 'Office', }, { date: '2016-05-04', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', tag: 'Home', }, { date: '2016-05-01', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', tag: 'Office' } ] </script>
3.第二种修改过el-table组件的样式
(1)我这里是修改过el-table的滚动条样式
(2)以下没修改过的
(3)原因分析
从上面两张图片可以看出,它们区别在于输出的(table1Wrapper )第二级一个事table标签,一个不是table标签。所以像第二种修改过el-table组件样式的就不再适用第一种的写法,因为没有拿对节点,要拿的节点不再是.el-table__body-wrapper而是.el-scrollbar__wrap,其他写法就与第一种写法无异。
(4)实现代码
<div> <el-table :data="tableData" id="table1" @selection-change="handleSelect" border height="40vh" scrollbar-always-on> <el-table-column width="60" fixed type="selection" />> <el-table-column width="120" prop="omsCostItemDto.costName" label="计费项名称" /> <el-table-column prop="omsCostItemDto.profit" label="利润" /> <el-table-column width="100" prop="omsCostItemDto.merchandiser" label="跟单员" /> </el-table> <el-table :data="tableData" id="table2" border height="40vh" scrollbar-always-on> <el-table-column width="120" prop="omsReceiveDto.writeOffAmount" label="核销金额" /> <el-table-column width="120" prop="omsReceiveDto.notReceivedAmount" label="未收金额" /> <el-table-column width="180" prop="omsReceiveDto.receiveCreateDate" label="账单生成时间" /> </el-table> <el-table :data="tableData" id="table3" border height="40vh" scrollbar-always-on> <el-table-column width="180" prop="omsPayDto.serviceProvidersName" label="服务商名称" class-name="unconfirmed" /> <el-table-column width="180" prop="omsPayDto.meetName" label="应付企业名称" /> </el-table> </div>
onMounted(() => { getList(); // 获取列表数据 setTimeout(() => { // 实现同步竖向滚动 nextTick(() => { let table1Wrapper = document.getElementById('table1').getElementsByClassName('el-scrollbar__wrap')[0] let table2Wrapper = document.getElementById('table2').getElementsByClassName('el-scrollbar__wrap')[0] let table3Wrapper = document.getElementById('table3').getElementsByClassName('el-scrollbar__wrap')[0] console.log("table1Wrapper",table1Wrapper); table1Wrapper.addEventListener('scroll', () => { table2Wrapper.scrollTop = table1Wrapper.scrollTop; table3Wrapper.scrollTop = table1Wrapper.scrollTop; }) table2Wrapper.addEventListener('scroll', () => { table1Wrapper.scrollTop = table2Wrapper.scrollTop; table3Wrapper.scrollTop = table2Wrapper.scrollTop; }) table3Wrapper.addEventListener('scroll', () => { table1Wrapper.scrollTop = table3Wrapper.scrollTop; table2Wrapper.scrollTop = table3Wrapper.scrollTop; }) }) }, 1000); })
(5)代码说明
1.为什么要放到onMounted里
可以放在一个方法里,但是也需要放在onMounted,这样就可以监听到滚动事件而不需要用watch来监听
2.为什么要使用setTimeout和nextTick
照理来说使用onMounted声明周期就可以了,因为它的作用是挂在后,数据和节点都已经生成;我这里不知道什么原因不使用setTimeout和nextTick就拿不到节点,数据倒是已生成(可能是我把getList(); // 获取列表数据放在了前面)
3.重点
重点在于document.getElementById('table1').getElementsByClassName('el-scrollbar__wrap')[0]获取正确的节点,第一种情况和第二种情况区别在于怎么拿到对的节点
4.总结
说白会出现第一种情况和第二种情况在于节点没有拿对
最后
以上就是vue3实现多个表格同时滚动并固定表头的详细内容,更多关于vue3表格同时滚动的资料请关注脚本之家其它相关文章!