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 分钟前
告别 ARouter!基于 Google 官方 Navigation 3 + KSP 打造 Compose 时代的双轨制路由框架
android·前端
ITmaster073138 分钟前
前端 AI 面试题:高频考点与实战解析
前端·人工智能
赵大仁41 分钟前
Structured Output 落地:JSON Schema、重试与前端校验
前端·ai·大模型·工程化·json schema
李剑一1 小时前
有点干,前端架构基础之:Web Worker到底是什么?它和Java中的线程是一个道理吗?
前端·面试·架构
爱勇宝2 小时前
《道德经》第 10 章:真正成熟的人,能成事但不控制一切
前端·后端·程序员
界面开发小八哥2 小时前
界面控件DevExpress Blazor v26.1新版亮点 - Navigation(导航)
javascript·.net·界面控件·blazor·devexpress·ui开发
aXin_ya2 小时前
ElementUI (01):Vue2 项目引入 ElementUI使用
elementui·vue
看谷秀2 小时前
arkts- 8 三方库介绍
前端·arkts
六边形6662 小时前
独立开发不知道做什么?使用 TRAE Work 抓取差评痛点,快速跑通产品立项流
前端·后端·面试
亿元程序员2 小时前
小伙伴发我一个 1G 的 Cocos 项目,assets 只有几十兆
前端