elementui中表格的表头固定 侧边列表固定 滚动条在头部 且使用鼠标滚轮横向时 可同步给顶部滚动条

html

javascript 复制代码
  <!-- 1. 自定义顶部滚动条 -->
    <div 
      class="custom-scrollbar-top" 
      ref="topScrollbar"
      @scroll="handleTopScroll"
    >
      <!-- 内部占位 div,宽度由 JS 动态设置为表格内容的实际宽度 -->
      <div class="scroll-track" :style="{ width: scrollContentWidth + 'px' }"></div>
    </div>
      <!-- 结果表格区域 -->
      <el-table
    :data="tableData"
    style="width: 100%"
    class="industryNewstable"
    ref="myTable"
    max-height="800">
    <el-table-column
      fixed="left"
      prop="date"
      label="日期"
      width="150">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名"
      width="120" fixed="left">
    </el-table-column>
    <el-table-column
      prop="province"
      label="省份"
      width="120" fixed="left">
    </el-table-column>
    <el-table-column
      prop="city"
      label="市区"
      width="120">
    </el-table-column>
    <el-table-column
      prop="address"
      label="地址"
      width="300">
    </el-table-column>
    <el-table-column
      prop="zip"
      label="邮编"
      width="120">
    </el-table-column>
  </el-table>

JS

javascript 复制代码
mounted() {
    this.$nextTick(() => {
      this.initScrollbarWidth();
      // 监听窗口变化,防止响应式布局导致宽度计算不准
      window.addEventListener('resize', this.initScrollbarWidth);
    });
  },
  beforeDestroy() {
    // 清理监听器,防止内存泄漏
    const table = this.$refs.myTable;
    if (table && table.$refs.bodyWrapper && this._tableScrollHandler) {
      table.$refs.bodyWrapper.removeEventListener('scroll', this._tableScrollHandler);
    }
    window.removeEventListener('resize', this.initScrollbarWidth);
  },
  methods: {
     // 1. 初始化顶部滚动条的总宽度(必须等于表格内容的实际宽度)
    initScrollbarWidth() {
      const table = this.$refs.myTable;
      if (table && table.$refs.bodyWrapper) {
        // 计算宽度// bodyWrapper.scrollWidth 是内容的真实宽度
        this.scrollContentWidth = table.$refs.bodyWrapper.scrollWidth;

        // 【关键步骤】移除旧的监听器(防止重复绑定),然后添加新的
        const bodyWrapper = table.$refs.bodyWrapper;
        
        // 使用一个绑定的函数引用,方便后续移除(如果需要在 beforeDestroy 移除)
        if (!this._tableScrollHandler) {
          this._tableScrollHandler = this.handleNativeTableScroll.bind(this);
        }
        
        bodyWrapper.removeEventListener('scroll', this._tableScrollHandler);
        bodyWrapper.addEventListener('scroll', this._tableScrollHandler);
      }
    },

    // 2. 当拖动【表格】(或使用鼠标滚轮横向) 时 -> 同步给顶部滚动条
    handleNativeTableScroll(event) {
      // event.target 就是 bodyWrapper
      const scrollLeft = event.target.scrollLeft;
      const topBar = this.$refs.topScrollbar;

      if (topBar) {
        // 只有当顶部滚动条位置和表格不一致时才更新,防止死循环
        // 注意:这里不需要判断 event 是横向还是纵向,scrollLeft 为 0 时赋值也没关系
        if (Math.abs(topBar.scrollLeft - scrollLeft) > 1) {
          topBar.scrollLeft = scrollLeft;
        }
      }
      
      // 如果你还需要处理垂直滚动同步(例如自定义垂直条),可以在这里加
      // const scrollTop = event.target.scrollTop;
    },

    // 当拖动【顶部自定义滚动条】时 -> 同步给表格
    handleTopScroll(event) {
      const table = this.$refs.myTable;
      if (table && table.$refs.bodyWrapper) {
        // 直接设置表格主体的 scrollLeft
        table.$refs.bodyWrapper.scrollLeft = event.target.scrollLeft;
        // 同步表头(防止表头和内容错位)
        if(table.$refs.headerWrapper) {
           table.$refs.headerWrapper.scrollLeft = event.target.scrollLeft;
        }
      }
    },
    }

css

javascript 复制代码
/* 自定义头部滚动条 op */
.table-wrapper {
  position: relative;
  /* 确保容器宽度正常 */
  width: 100%; 
}

/* --- 顶部自定义滚动条样式 --- */
.custom-scrollbar-top {
  width: 100%;
  height: 14px; /* 滚动条高度 */
  overflow-x: auto;
  overflow-y: hidden;
  background-color: #f5f7fa; /* 与表头背景一致 */
  margin-bottom: 0;
  border-bottom: 1px solid #ebeef5; /* 与表头底部分隔线 */
  border-radius: 4px 4px 0 0;
}

/* 内部轨道占位符 */
.scroll-track {
  height: 1px;
  /* width 由 JS 动态绑定 */
}

/* 美化顶部滚动条 (Chrome/Edge/Safari) */
.custom-scrollbar-top::-webkit-scrollbar {
  height: 14px;
}
.custom-scrollbar-top::-webkit-scrollbar-track {
  background: #f5f7fa;
  border-radius: 7px;
}
.custom-scrollbar-top::-webkit-scrollbar-thumb {
  background: #c0c4cc;
  border-radius: 7px;
  border: 3px solid #f5f7fa; /* 增加边距感 */
}
.custom-scrollbar-top::-webkit-scrollbar-thumb:hover {
  background: #909399;
}

/* 美化顶部滚动条 (Firefox) */
.custom-scrollbar-top {
  scrollbar-width: thin;
  scrollbar-color: #c0c4cc #f5f7fa;
}

/* --- 关键:隐藏 Element UI 表格底部的原生滚动条 --- */
::v-deep .industryNewstable .el-table__body-wrapper::-webkit-scrollbar {
  height: 0px !important; /* 强制高度为0 */
  background: transparent;
}
::v-deep .industryNewstable .el-table__body-wrapper::-webkit-scrollbar-track {
  background: transparent;
}
::v-deep .industryNewstable .el-table__body-wrapper::-webkit-scrollbar-thumb {
  background: transparent;
}

/* Firefox 隐藏底部滚动条 */
::v-deep .industryNewstable .el-table__body-wrapper {
  scrollbar-width: none; /* Firefox 64+ */
  -ms-overflow-style: none; /* IE/Edge */
}

/* --- 保持你之前的单元格内容限制样式 --- */
.industryNewstable.el-table /deep/ .cell-scroll-content::-webkit-scrollbar {
  width: 3px;  /* 垂直滚动条宽度 */
}
/* 自定义头部滚动条 end */
.industryNewstable.el-table /deep/ .el-table__fixed{
  bottom:0px !important;
  background-color:#fff;
}
相关推荐
我是若尘17 小时前
Harness Engineering:2026 年 AI 编程的核心战场
前端·后端·程序员
weixin1997010801617 小时前
《快手商品详情页前端性能优化实战》
前端·性能优化
IT_陈寒18 小时前
折腾一天才明白:Vite的热更新为什么偶尔会罢工
前端·人工智能·后端
AI茶水间管理员19 小时前
学习ClaudeCode源码之Agent核心循环
前端·人工智能·后端
挖稀泥的工人19 小时前
AI聊天界面的布局细节和打字跟随方法
前端·javascript·面试
竹林81819 小时前
从“连接失败”到丝滑登录:我用 ethers.js 连接 MetaMask 的完整踩坑记录
前端·javascript
颜酱19 小时前
图片大模型实践:可灵(Kling)文生图前后端实现
前端·javascript·人工智能
Reart19 小时前
从0解构tinyWeb项目--(Day:2)
javascript·后端·架构
木斯佳19 小时前
前端八股文面经大全:腾讯CSIG实习面(2026-04-10)·面经深度解析
前端·ai·xss·埋点·实习面经
夏暖冬凉20 小时前
npm发布流程(记录遇到的问题)
前端·npm·node.js