vue3中多个表格怎么同时滚动并且固定表头

说明:这里需分为两种情况来做。第一种亲情况就是没有修改过el-table这个组件的样式;第二种情况就是修改过el-table组件的样式。第一种较为简单就简单略过,这里主要提及第二种做法。

1.需求效果

2.第一种没有修改过el-table这个组件的样式的做法

(1)直接看大佬vue2的做法

https://blog.csdn.net/z1761419224/article/details/120510842

(2)以下是vue3写法(可以直接使用看看效果,没效果的就看第二种方法)

javascript 复制代码
<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)实现代码

html 复制代码
<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>
javascript 复制代码
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.总结

说白会出现第一种情况和第二种情况在于节点没有拿对

相关推荐
要加油哦~19 分钟前
JS | 知识点总结 - 原型链
开发语言·javascript·原型模式
哆啦A梦15881 小时前
axios 的二次封装
前端·vue.js·node.js
阿珊和她的猫1 小时前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
yinuo1 小时前
一行 CSS 就能搞定!用 writing-mode 轻松实现文字竖排
前端
snow@li2 小时前
html5:拖放 / demo / 拖放事件(Drag Events)/ DataTransfer 对象方法
前端·html·拖放
爱看书的小沐2 小时前
【小沐杂货铺】基于Three.js渲染三维风力发电机(WebGL、vue、react、WindTurbine)
javascript·vue.js·webgl·three.js·opengl·风力发电机·windturbine
qq_398586542 小时前
Threejs入门学习笔记
javascript·笔记·学习
浪裡遊3 小时前
Nivo图表库全面指南:配置与用法详解
前端·javascript·react.js·node.js·php
課代表3 小时前
JavaScript 二维数组的三种定义与初始化方法
javascript·初始化·二维数组·多维数组·动态数组·循环遍历·数组合并
鸡吃丸子4 小时前
Next.js 入门指南
开发语言·javascript·next.js