vue在表格组件外自定义滚动条控制表格横向滑动内容

438 阅读2分钟

问题概括

由于表格设置右边固定操作栏,左侧展示了许多的字段内容需要左右滚动进行浏览

  • 一旦内容区数据多了就要将右侧的纵向滚动条拉到最底部才能拖动横向的滚动条进行左右滚动 在这里插入图片描述

解决办法

  • 不显示原表格的滚动条,并在表格组件之外自定义滚动条固定到底部
  • 设置自定义滚动条左右拖动效果并同步拖动表格左右滑动

主要代码

自定义滚动条

  • html部分
    <!--        自定义滚动条-->
    <div ref="tableRef">
        ...表格区域
    </div>
    <div class="horizontal-scroll" v-if="showScroll">
        <div
        class="scroll-thumb"
        :style="thumbStyle"
        @mousedown="startDrag">
        </div>
    </div>
  • css部分:==注意还需要隐藏原表格的横向滚动条==
.horizontal-scroll {
    overflow: hidden;
    position: absolute;
    // 以下自行调整滚动条高度和宽度以及定位
    height: 6px;
    top: -4px;
    left: 0;
    width: calc(100% - 180px); 
    background: #eaeaea;
    z-index: 999;

    .scroll-thumb {
        position: absolute;
        height: 100%;
        width: 100%;
        background-color: #b2b2b2;
        border-radius: 4px;
    }

    .scroll-thumb:hover {
        background: #747474;
    }
}

同步拖动滚动条控制表格横向滚动

  • 初始化滚动条宽度和滑块宽度距离
  • 控制滚动条滚动和滑动表格
data(){
    return{
        isDragging: false,
        startX: 0,
        startScrollLeft: 0,
        // 内容宽度和滚动条宽度
        contentWidth: 0, // 替换为你的实际内容宽度
        scrollTrackWidth: 0, // 替换为你的滚动条宽度
        showScroll: true,
    }
},
mounted() {
    // 在组件挂载时监听窗口的尺寸变化事件
    window.addEventListener("resize", this.updateScrollTrackWidth);
    // 初始化自定义滚动条宽度
    this.SetScrollAttr()
},
beforeDestroy() {
    // 在组件销毁前移除窗口尺寸变化事件监听
    window.removeEventListener("resize", this.updateScrollTrackWidth);
},
computed: {
    // 计算滚动条距左侧的距离和长度,返回滚动条绑定的动态样式
    thumbStyle() {
    const thumbLeft =(this.startScrollLeft / this.contentWidth) * this.scrollTrackWidth;
        return {
            left: `${thumbLeft}px`,
            width: `${(this.scrollTrackWidth / this.contentWidth) * 100}%`,
        };
},
methods: {
    // 初始化自定义滚动条宽度
    SetScrollAttr() {
         // 初始化显示自定义滚动条
        this.showScroll = true;
        // 获取左侧表格的实际内容宽度
        this.contentWidth = this.$refs.tableRef.scrollWidth;
        // 获取左侧表格视图显示的宽度即滚动条长度
        this.scrollTrackWidth = this.$refs.tableRef.clientWidth;
        // 判断实际宽度是否大于或者小于视图显示宽度,是则隐藏自定义的滚动条
        if (this.contentWidth <= this.scrollTrackWidth) {
            this.showScroll = false;
        }
    },
    // 每次窗口变化则再次初始化自定义滚动条宽度
    updateScrollTrackWidth() {
        this.SetScrollAttr();
    },
    // 触发自定义mousedown事件
    startDrag(event) {
        this.isDragging = true;
        this.startX = event.clientX;
        this.startScrollLeft = this.startScrollLeft;
        document.addEventListener("mousemove", this.onDrag);
        document.addEventListener("mouseup", this.stopDrag);
    },
    // 鼠标拖动事件
    onDrag(event) {
        if (this.isDragging) {
            // 鼠标拖动的时候禁止选中文字
            window.getSelection ? window.getSelection().removeAllRanges():document.selection.empty();
            // 计算拖动距离
            const deltaX = event.clientX - this.startX;
            // 控制表格左右滑动
            const newScrollLeft = this.startScrollLeft + (deltaX * this.contentWidth) / this.scrollTrackWidth;
            this.startScrollLeft = Math.max(0,Math.min(this.contentWidth - this.scrollTrackWidth,newScrollLeft));
            this.$refs.tableRef.scrollLeft = this.startScrollLeft;
            this.startX = event.clientX;
            }
        },
        // 鼠标抬起事件
        stopDrag() {
            // 关闭是否点击拖动标记
            this.isDragging = false;
            // 关闭鼠标移动和抬起事件
            document.removeEventListener("mousemove", this.onDrag);
            document.removeEventListener("mouseup", this.stopDrag);
        },
},

希望能够帮助到大家!如果大佬们有更好的方法,也欢迎大佬们一起分享探讨!感谢观看!