You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue JS中如何基于另一div设置div宽度以实现表格双滚动?

实现动态宽度表格的双滚动同步效果

问题分析

你遇到的核心问题有两个:一是模板中样式绑定的语法错误,二是获取DOM元素宽度的时机不对,导致无法同步div1和content的宽度,进而影响滚动同步。

解决方案

以下是完整的实现方案,包含修正后的模板、脚本和样式:

1. 修正模板代码

<template>
  <div class="scroll-container">
    <!-- 顶部滚动条容器 -->
    <div class="wrapper1" @scroll.passive="handleScroll1" ref="wrapper1">
      <div class="div1" :style="{ width: `${contentWidth}px` }"></div>
    </div>
    <!-- 内容滚动容器 -->
    <div class="wrapper2" @scroll.passive="handleScroll2" ref="wrapper2">
      <div class="content" ref="content">
        <!-- 这里放置你的表格内容 -->
        <table>
          <!-- 动态列的内容区域 -->
        </table>
      </div>
    </div>
  </div>
</template>

2. 脚本逻辑实现

<script>
export default {
  data() {
    return {
      contentWidth: 0,
      isScrolling: false // 防止滚动事件循环触发
    }
  },
  mounted() {
    // 初始化获取内容宽度
    this.updateContentWidth()
    // 监听窗口缩放,适配宽度变化
    window.addEventListener('resize', this.updateContentWidth)
  },
  watch: {
    // 假设你的列数据存在columns数组中,列变化时自动更新宽度
    columns: {
      handler() {
        this.updateContentWidth()
      },
      deep: true
    }
  },
  methods: {
    updateContentWidth() {
      // 确保DOM渲染完成后再获取宽度
      this.$nextTick(() => {
        const contentEl = this.$refs.content
        if (contentEl) {
          // 使用scrollWidth获取内容实际总宽度(包含溢出部分)
          this.contentWidth = contentEl.scrollWidth
        }
      })
    },
    handleScroll1() {
      if (this.isScrolling) return
      this.isScrolling = true
      // 同步内容容器的滚动位置
      this.$refs.wrapper2.scrollLeft = this.$refs.wrapper1.scrollLeft
      this.$nextTick(() => {
        this.isScrolling = false
      })
    },
    handleScroll2() {
      if (this.isScrolling) return
      this.isScrolling = true
      // 同步顶部滚动条的滚动位置
      this.$refs.wrapper1.scrollLeft = this.$refs.wrapper2.scrollLeft
      this.$nextTick(() => {
        this.isScrolling = false
      })
    }
  },
  beforeDestroy() {
    // 移除窗口监听,避免内存泄漏
    window.removeEventListener('resize', this.updateContentWidth)
  }
}
</script>

3. 样式设置

<style scoped>
.scroll-container {
  width: 100%;
  overflow: hidden;
}
.wrapper1 {
  height: 20px; /* 顶部滚动条的高度 */
  overflow-x: auto;
  overflow-y: hidden;
  margin-bottom: -10px; /* 隐藏与内容容器滚动条的重叠部分 */
}
.div1 {
  height: 1px; /* 仅用于撑开滚动条,无需显示内容 */
}
.wrapper2 {
  overflow-x: auto;
  overflow-y: auto;
}
.content {
  white-space: nowrap; /* 确保表格列不换行,保持原始宽度 */
}
/* 可选:自定义滚动条样式 */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background-color: #ccc;
  border-radius: 5px;
}
</style>

关键说明

  • 样式绑定修正:原模板中直接使用style="width:${this.width} + 'px'"是错误的,Vue中需通过:style进行动态样式绑定,正确语法为:style="{ width: ${contentWidth}px }"。
  • 宽度获取时机:用$nextTick确保DOM更新完成后再获取元素宽度,避免因元素未渲染导致获取到0值;使用scrollWidth而非offsetWidth,因为scrollWidth能获取内容的实际总宽度(包含溢出部分),更适配滚动场景。
  • 滚动同步防循环:通过isScrolling标志位避免两个滚动事件互相触发,防止循环滚动问题。
  • 动态列适配:通过watch监听列数据变化,实时更新contentWidth,确保添加列后宽度能同步更新。

内容的提问来源于stack exchange,提问作者ajith sadanandan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 14:10:25