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
相关产品推荐
相关产品推荐

