vue表格轮播插件

1.前言

  • 需求:制作大屏看板时,经常要展示表格数据,通常一页时放不下的,表格需要自动滚动,并维持表头固定
  • 为何自己封装:网上的滚动组件有2类,一种传入json数据进行滚动(DataV),优点是可以做到表头固定,但是样式不方便自定义,一直是常规滚动插件,不支持表头固定

2.实现思路及说明

  • 组件高度默认100%,需要自行给父容器设定高度
  • 使用插槽接收表格内容,便于用户自定义表格样式
  • 表头固定使用position: sticky进行实现,其实就是一个吸顶效果,需要给表头一个背景色,防止滚动时表体内容内容透过来
  • 渲染完毕后计算可滚动距离,使用定时器进行滚动,滚动速度可配置,滚动到底则抛出事件
  • 支持鼠标悬停

3.使用方法

  • 引入该插件,将目标表格用此组件标签进行包裹
<zy-table-scroll @scrollToEnd="scrollToEnd" @noScroll="noScroll" :data="tableData">
    <table><table>
</zy-table-scroll>
  • 参数说明
参数 说明
data 表格数据,数组格式,用于监听数据变化,重置滚动
duration 每次滚动距离(px),默认10
step 滚动时间间隔(毫秒),默认0.2
@scrollToEnd 滚动到底事件
@noScroll 当数据不为空,但是没有产生滚动条时触发

4.插件代码

<template>
    <div class="table-scroll-wrap" ref="table-scroll-wrap" @mouseenter="mouseenterEvent" @mouseleave="mouseleaveEvent">
        <slot></slot>
    </div>
</template>

<script>
export default{
    props: {
        data: {
            type:Array,
            default: function(){
                return []
            }
        },
        //滚动间隔(毫秒)
        duration: {
            type: Number,
            default: 10
        },
        //每次滚动距离(px)
        step: {
            type: Number,
            default: 0.2
        },
        //滚动延迟(毫秒)
        delay: {
            type: Number,
            default: 1000
        },
        //是否鼠标移入停止滚动
        hoverStop: {
            type: Boolean,
            default: true
        }
    },
    data(){
        return {
            timer: null,//定时器

            mouseInBox: false,//鼠标是否在容器内
        }
    },
    //这里不用update,而是用watch进行监听,是因为插槽的缘故,会导致update异常
    watch: {
        data(){
            //等待渲染完毕
            this.$nextTick(()=>{
                //初始化滚动
                this.initScroll()
            })
        }
    },
    mounted(){
        //初始化滚动
        this.initScroll()
    },
    beforeDestroy(){
        //清除定时器
        clearInterval(this.timer)
        clearTimeout(this.timerDelay)
    },
    methods: {
        //初始化滚动
        initScroll(){
            var box = this.$refs['table-scroll-wrap']
            //计算滚动距离
            var scrollDistance = box.scrollHeight - box.clientHeight
            //回到顶部
            box.scrollTo({
                top: 0
            })
            //没产生滚动,不做处理
            if(scrollDistance <= 0){
                //事件抛出(空列表不抛出,防止数据冲突)
                if(this.data.length > 0){
                    this.$emit('noScroll')
                }
                return
            }
            //如果开启了悬停,且鼠标处于悬停状态
            if(this.hoverStop && this.mouseInBox){
                return
            }
            //清除旧定时器
            clearTimeout(this.timerDelay)
            //延迟定时器
            this.timerDelay = setTimeout(()=>{
                //开始滚动
                this.startScroll()
            },this.delay)
            
        },
        //开启滚动
        startScroll(){
            var box = this.$refs['table-scroll-wrap']
            //计算滚动距离
            var scrollDistance = box.scrollHeight - box.clientHeight
            //当前滚动距离
            var scrollTop = box.scrollTop
            //已经到底,或者没有滚动距离,不执行
            if(scrollTop >= scrollDistance || scrollDistance <= 0){
                return
            }
            //清除旧定时器
            clearInterval(this.timer)
            //开启定时器
            this.timer = setInterval(()=>{
                //进行滚动
                if(scrollTop >= scrollDistance){
                    //清除定时器
                    clearInterval(this.timer)
                    //事件抛出
                    this.$emit('scrollToEnd')
                }else{
                    //执行滚动
                    scrollTop += this.step
                    box.scrollTo({
                        top: scrollTop
                    })
                }
            },this.duration)
        },
        //终止滚动
        stopScroll(){
            //清除定时器
            clearInterval(this.timer)
            clearTimeout(this.timerDelay)
        },
        //鼠标移入
        mouseenterEvent(){
            this.mouseInBox = true
            if(this.hoverStop){
                //终止滚动
                this.stopScroll()
            }
        },
        //鼠标移出
        mouseleaveEvent(){
            this.mouseInBox = false
            if(this.hoverStop){
                //重新开启滚动
                this.startScroll()
            }
        }
    }
}
</script>


<style scoped lang="scss">
.table-scroll-wrap{
    height: 100%;
    overflow: auto;
    &::-webkit-scrollbar {
        width: 0;
    }
    table{
        tr{
            &:first-child{
                position: sticky;
                top:0;
            }
        }
    }
}
</style>
posted @ 2024-10-12 16:27  ---空白---  阅读(103)  评论(0编辑  收藏  举报