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;
}
相关推荐
llxxyy卢2 小时前
polar春季赛web题目
前端·web安全
SuperEugene2 小时前
Axios 统一封装实战:拦截器配置 + baseURL 优化 + 接口规范,避坑重复代码|API 与异步请求规范篇
前端·javascript·vue.js·前端框架·axios
Alan Lu Pop2 小时前
Figma 配置
前端·ai编程·cursor
Moment2 小时前
手把手搭一套前端监控采集 SDK
前端·javascript·面试
华洛2 小时前
实战指南:企业如何选择AI需求的落地技术方案
前端·产品经理·产品
莫爷2 小时前
JSON vs XML vs YAML 深度对比:如何选择合适的数据格式?
xml·前端·json
We་ct2 小时前
LeetCode 33. 搜索旋转排序数组:O(log n)二分查找
前端·算法·leetcode·typescript·个人开发·二分·数组
华仔啊2 小时前
前端不懂 Java?后端怕 CSS?这套AI全栈方案专治各种偏科
java·前端·后端
木斯佳2 小时前
前端八股文面经大全:得物AI应用开发一面(2026-03-23)·面经深度解析【加精】
前端·人工智能·ai·markdown·chat·rag