vue3+element-plus实现两个表格同步滚动功能

 更新时间:2025年06月28日 10:54:56   作者:mini_055  
现在需要两个表格,为了方便对比左右的数据,需要其中一边的表格滚动时,另一边的表格也跟着一起滚动,并且保持滚动位置的一致性,本文给大家介绍vue3+element-plus实现两个表格同步滚动功能,感兴趣的朋友一起看看吧

需求:现在需要两个表格,为了方便对比左右的数据,需要其中一边的表格滚动时,另一边的表格也跟着一起滚动,并且保持滚动位置的一致性。具体如下图所示。

实现步骤:

  1. 确保两个表格的宽度一致:如果两个表格的宽度不一致,可能会导致滚动条的位置不同步。确保两个表格的宽度相同(数据内容超出表格行的宽度可以省略显示)或根据需要调整。

  2. 使用相同的滚动容器:确保两个表格的滚动容器具有相同的高度,这样它们的滚动行为才会同步。

  3. 同步滚动事件:在两个表格上监听滚动事件,并在事件触发时同步另一个表格的滚动位置。

HTML结构:

创建一个包含两个表格的容器,然后给容器一个固定的高度(因为要实现滚动必须要内容超过高度了才会滚动)。

<template>
  <div class="container-box">
    <div class="flex table-box">
      <!-- 左边表格 -->
      <div class="left-table" ref="leftTableWrapper">
        <el-table
          :data="LeftTableData"
          border
          ref="leftTableRef"
          style="width: 100%"
          height="100%"
          :fit="true"
          header-row-class-name="header-row"
          :cell-style="{
            'font-size': '12px',
            color: '#666666',
            height: '40px',
          }"
        >
          <template #empty>
            <div class="custom-empty">
              <el-empty
                :image="`${$global.imageBaseUrl}/ledger/billProcessing/icon_nodata.png`"
                description="暂无数据"
              />
            </div>
          </template>
          <el-table-column
            label="表头1"
            prop="left1"
            align="center"
            min-width="150"
          />
          <el-table-column
            label="表头2"
            prop="left2"
            align="center"
            width="100"
          />
        </el-table>
      </div>
      <!-- 右边表格 -->
      <div class="right-table" ref="rightTableWrapper">
        <el-table
          :data="rightTableData"
          border
          ref="rightTableRef"
          style="width: 100%"
          height="100%"
          :fit="true"
          header-row-class-name="header-row"
          :cell-style="{
            'font-size': '12px',
            color: '#666666',
            height: '40px',
          }"
        >
          <template #empty>
            <div class="custom-empty">
              <el-empty
                :image="`${$global.imageBaseUrl}/ledger/billProcessing/icon_nodata.png`"
                description="暂无数据"
              />
            </div>
          </template>
          <el-table-column
            label="表头1"
            prop="right1"
            align="center"
            min-width="150"
          />
          <el-table-column
            label="表头2"
            prop="right2"
            align="center"
            width="100"
          />
        </el-table>
      </div>
    </div>
  </div>
</template>

JavaScript逻辑:

  • 模拟左右表格的数据,初始设置100条。

  • 在两个表格上监听滚动事件,并在事件触发时同步另一个表格的滚动位置。

  • 使用nextTick确保DOM更新完成后再同步滚动位置。

  • setupTableScrollSync 函数通过获取 el-table 的 body 容器,给左右表格的滚动事件绑定同步逻辑,避免循环触发(用 isSyncingScroll 标记)。

<script lang="ts" setup>
interface tableInfo {
  left1?: string
  left2?: string
  right1?: string
  right2?: string
}
let LeftTableData = ref<tableInfo[]>([])
let rightTableData = ref<tableInfo[]>([])
const leftTableRef = ref()
const rightTableRef = ref()
const leftTableWrapper = ref()
const rightTableWrapper = ref()
onMounted(() => {
  for (let index = 0; index < 100; index++) {
    let obj = {
      left1: `表${index + 1}`,
      left2: `表${index + 1}-1`,
    }
    let obj2 = {
      right1: `表${index + 1}`,
      right2: `表${index + 1}-1`,
    }
    LeftTableData.value.push(obj)
    rightTableData.value.push(obj2)
  }
  // 表格滚动同步
  nextTick(() => {
    setupTableScrollSync()
  })
})
// 滚动同步实现
let isSyncingScroll = false
function setupTableScrollSync() {
  // 获取表格body的滚动容器
  const getTableBodyWrapper = (tableRef: any) => {
    // el-table exposes $el, then .querySelector('.el-scrollbar__wrap')
    // 兼容 el-table 2.x/3.x
    if (!tableRef?.value) return null
    // 先找新版class
    let body = tableRef.value.$el.querySelector('.el-scrollbar__wrap')
    if (!body) {
      // 旧版class
      body = tableRef.value.$el.querySelector('.el-table__body-wrapper')
    }
    return body
  }
  const leftBody = getTableBodyWrapper(leftTableRef)
  const rightBody = getTableBodyWrapper(rightTableRef)
  if (!leftBody || !rightBody) return
  // 解绑旧的监听,防止重复
  leftBody.onscroll = null
  rightBody.onscroll = null
  leftBody.onscroll = (e: Event) => {
    if (isSyncingScroll) return
    isSyncingScroll = true
    rightBody.scrollTop = leftBody.scrollTop
    isSyncingScroll = false
  }
  rightBody.onscroll = (e: Event) => {
    if (isSyncingScroll) return
    isSyncingScroll = true
    leftBody.scrollTop = rightBody.scrollTop
    isSyncingScroll = false
  }
}
</script>

CSS 样式:

<style lang="scss" scoped>
.container-box {
  background-color: #fff;
  border-radius: 4px;
  margin: 16px;
  height: calc(100vh - 100px);
  padding: 24px;
  .table-box {
    height: calc(100% - 465px);
    .left-table {
      margin-right: 16px;
    }
    .left-table,
    .right-table {
      :deep(.header-row th) {
        background-color: #f5f5f5;
        text-align: center;
      }
    }
  }
}
</style>

想要实现表格同步滚动,其实还有一个办法,就是用一个表格来实现(前提是数据是放在一个数组里的) ,然后中间想要空隙,通过CSS样式为表格的某些行或列添加间隔,这种方法实现简单,无需处理滚动逻辑。如果需要真正的固定列+滚动列效果,推荐用两个表格来实现;如果只是视觉分隔,一个表格来实现更简单。

到此这篇关于vue3+element-plus,实现两个表格同步滚动的文章就介绍到这了,更多相关vue3 element-plus表格同步滚动内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在Vue3中为路由Query参数标注类型的方法

    在Vue3中为路由Query参数标注类型的方法

    这篇文章主要介绍了在Vue3中如何为路由Query参数标注类型,我们就针对这个话题如何为路由Query参数标注类型为例,看看Composable和IOC容器的代码风格究竟有什么不同,需要的朋友可以参考下
    2024-08-08
  • 详解Vue使用命令行搭建单页面应用

    详解Vue使用命令行搭建单页面应用

    本篇文章主要介绍了详解Vue使用命令行搭建单页面应用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 深入了解Vue3 中 this的使用

    深入了解Vue3 中 this的使用

    在Vue3中,this的使用方式与Vue2存在较大差异,尤其是在引入组合式API后,本文详细解析了Vue3中this的使用情况、底层源码和设计理念,并提供了面试技巧,感兴趣的可以了解一下
    2024-09-09
  • 关于vue-cli 3配置打包优化要点(推荐)

    关于vue-cli 3配置打包优化要点(推荐)

    这篇文章主要介绍了vue-cli 3配置打包优化要点,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • vue实现跨页面定位锚点区域方式

    vue实现跨页面定位锚点区域方式

    这篇文章主要介绍了vue实现跨页面定位锚点区域方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • Vue3中Tree树组件开发文档(附使用示例)

    Vue3中Tree树组件开发文档(附使用示例)

    在Vue中树形组件是一种用于展示层级结构数据的UI组件,常用于展示如文件目录、组织架构等具有层级关系的数据,这篇文章主要介绍了Vue3中Tree树组件开发文档的相关资料,需要的朋友可以参考下
    2026-03-03
  • vue修改props数据报错的问题及解决

    vue修改props数据报错的问题及解决

    这篇文章主要介绍了vue修改props数据报错的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Vue3+Spring Framework框架开发实战

    Vue3+Spring Framework框架开发实战

    这篇文章主要为大家介绍了Vue3+Spring Framework框架开发实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • vue生命周期和react生命周期对比【推荐】

    vue生命周期和react生命周期对比【推荐】

    本文通过实例代码给大家介绍了vue生命周期和react生命周期对比 ,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • vue中axios解决跨域问题和拦截器的使用方法

    vue中axios解决跨域问题和拦截器的使用方法

    下面小编就为大家分享一篇vue中axios解决跨域问题和拦截器的使用方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03

最新评论