首页 默认分类 正文
  • 本文约2583字,阅读需13分钟
  • 55
  • 0

vue2 el-table列表组件自动滚动

摘要

基于elementui el-table组件的二次封装,适用列表自动滚动。其中包括单行滚动、整页滚动(除表头外的可视区域)、像素滚动。

1. 声明组件

demo

./autoTableList.vue

<script>
    import { Table } from 'element-ui';
    export default {
            name: 'autoTableList',
            props: {
                     // 播放类型 row | continuous | page
                     // row 每次滚动一行
                     // continuous 连续滚动
                     // page 整页滚动
                     type: {
                             typeof: String,
                             default: 'continuous'
                     },
                     // 是否需要动画过度 
                     // 仅 type='row'|'page'生效 默认为true
                     isAnimation: {
                             typeof: Boolean,
                             default: true
                     },
                    // 滚动速率 (每秒) 仅 type='continuous'生效 默认30 
                     speed: {
                             typeof: [Number, String],
                             default: 100
                     },
                    // 播放结束后等待多少时间重新播放 
                    endDelay: {
                            typeof: [Number, String],
                            default: 2000
                    },
                    // 单次过度时间,单位:毫秒。 默认值为 300毫秒
                    singleDuration: {
                            typeof: [Number, String],
                            default: 300
                    },
                    // 单次等待间隔,单位:毫秒。 默认值为 3000 毫秒
                    singleDelay: {
                            typeof: [Number, String],
                            default: 3000
                    },
                    // 是否允许鼠标hover控制。即鼠标进入停止,移出继续播放 默认为true
                    hoverStep: {
                            typeof: Boolean,
                            default: true
                    },
                    // 鼠标离开时等待多少秒开始播放仅在hoverStep为true是生效 单位:毫秒。 默认值为 3000 毫秒
                    hoverDelay: {
                            typeof: [Number, String],
                            default: 3000
                    },
            },
            extends: Table,
            data() {
                    return {
                            autoTable: {
                                    playTimer: null,
                                    singleDelayTimer: null,
                                    playIndex: 0,
                            }
                    }
            },
            watch: {
                    data: {
                          handler(newVal, oldVal) {
                                this.updateAutoTableVal()
                          },
                          deep: true
                    }
            },
            methods: {
                    updateAutoTableVal() {
                          this.autoTable.bodyWrapper = this.$el.querySelector('.el-table__body-wrapper');
                          this.autoTable.tableBody = this.autoTable.bodyWrapper.querySelectorAll('.el-table__body')[0];
                          this.autoTable.maxHeight = this.autoTable.tableBody.offsetHeight;
                          this.autoTable.clientHeight = this.autoTable.bodyWrapper.clientHeight;
                      },
                     autoPlay() {
                          if (this.autoTable.bodyWrapper.scrollTop >= (this.autoTable.maxHeight - this.autoTable.clientHeight)) {
                                clearInterval(this.autoTable.playTimer)
                                this.autoTable.singleDelayTimer=setTimeout(() => {
                                      this.autoTable.bodyWrapper.scrollTop = 0;
                                      this.autoTable.playIndex = 0
                                      this.autoTable.playTimer = setInterval(this.autoPlay, this.singleDelay);
                                }, this.endDelay);
                                return
                              } else {
                                    this.autoTable.playIndex++
                                    let end = 0;
                                    if(this.type=='row'){
                                        end = this.autoTable.tableBody.querySelectorAll('.el-table__row')[this.autoTable.playIndex].offsetTop;
                                    }else if(this.type=='page'){
                                        end = this.autoTable.bodyWrapper.offsetHeight* this.autoTable.playIndex
                                    }
                                    if (this.isAnimation) {
                                        this.scrollTo(this.autoTable.bodyWrapper, end, this.singleDuration);
                                    } else {
                                        this.autoTable.bodyWrapper.scrollTop = end;
                                    }
                              }
                        },
                        continuousPlay(){
                              this.autoTable.playTimer=setInterval(()=>{
                                    if (this.autoTable.bodyWrapper.scrollTop >= (this.autoTable.maxHeight - this.autoTable.clientHeight)) {
                                          clearInterval(this.autoTable.playTimer)
                                          this.autoTable.singleDelayTimer = setTimeout(() => {
                                                this.autoTable.bodyWrapper.scrollTop = 0;
                                                this.continuousPlay();
                                          }, this.endDelay);
                                          return
                                    }else{
                                        this.autoTable.bodyWrapper.scrollTop ++;
                                    }
                              },this.speed)
                        },
                        MouseEnter() {//鼠标移入停止滚动
                            clearInterval(this.autoTable.playTimer);
                        },
                        MouseLeave() {//鼠标离开继续滚动
                            this.autoTable.playTimer = setInterval(this.autoPlay, this.hoverDelay);
                        },
                        easeInOutQuad(t, b, c, d) {
                            t /= d / 2;
                            if (t < 1) return c / 2 * t * t + b;
                            t--;
                            return -c / 2 * (t * (t - 2) - 1) + b;
                        },
                        scrollTo(element, to, duration) {
                              const start = element.scrollTop;
                              const change = to - start;
                              const increment = 20;
                              let currentTime = 0;
                              let that = this;
                              function animateScroll() {
                                    currentTime += increment;
                                    const val = that.easeInOutQuad(currentTime, start, change, duration);
                                    element.scrollTop = val;
                                    if (currentTime < duration) {
                                         setTimeout(animateScroll, increment);
                                        }else{
                                          if (that.$listeners['complete']) {
                                                that.$emit('complete',{
                                                      dataIndex: that.autoTable.playIndex,
                                                      scrollTop:to,
                                                })
                                         }
                                    }
                              }
                             animateScroll();
                        },
                        restart(){
                              clearTimeout(this.autoTable.singleDelayTimer)
                              clearInterval(this.autoTable.playTimer);
                              this.autoTable.playIndex=0;
                              if(this.type=='continuous'){
                                    this.continuousPlay()
                              }else{
                                    this.autoTable.playTimer = setInterval(this.autoPlay, this.singleDelay);
                              }
                        },
            },
            async mounted() {
                    await this.$nextTick();
                    this.updateAutoTableVal()
                    this.restart()
                    if (this.hoverStep) {
                          this.autoTable.bodyWrapper.addEventListener('mouseenter', this.MouseEnter);
                          this.autoTable.bodyWrapper.addEventListener('mouseleave', this.MouseLeave);
                    }
            },
             beforeDestroy() {
                    clearTimeout(this.autoTable.singleDelayTimer)
                    clearInterval(this.autoTable.playTimer);
                    if (this.hoverStep) {
                          this.autoTable.bodyWrapper.removeEventListener('mouseenter', this.MouseEnter);
                          this.autoTable.bodyWrapper.removeEventListener('mouseleave', this.MouseLeave);
                    }
            },
    };
</script>

2.组件调用

./index.vue

<template>
         <autoTableList :data="tableData"  height="300" @complete="complete">
                 <el-table-column type="index" width="50"></el-table-column>
                 <el-table-column prop="date" label="日期" width="180"></el-table-column>
                 <el-table-column prop="name" label="姓名" width="180"></el-table-column>
                 <el-table-column prop="address" label="地址"></el-table-column>
         </autoTableList>
 </template>

<script>
        import autoTableList from './autoTableList1'
        export default {
                data() {
                        return {
                                tableData: [
                                        {
                                                date: '2016-05-04',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1517 弄'
                                        },
                                        {
                                                date: '2016-05-04',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1517 弄'
                                        },
                                        {
                                                date: '2016-05-04',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1517 弄'
                                        },
                                        {
                                                date: '2016-05-04',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1517 弄'
                                        },
                                        {
                                                date: '2016-05-04',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1517 弄'
                                        },
                                        {
                                                date: '2016-05-02',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1518 弄'
                                        },
                                        {
                                                date: '2016-05-04',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1517 弄'
                                        },
                                        {
                                                date: '2016-05-01',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1519 弄'
                                        },
                                        {
                                                date: '2016-05-01',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1519 弄'
                                        },
                                        {
                                                date: '2016-05-03',
                                                name: '王小虎',
                                                address: '上海市普陀区金沙江路 1516 弄'
                                        }
                                ],
                        }
                },
                components: {
                        autoTableList
                },
                methods: {
                        complete(data) {
                                console.log(data);
                        },
                }
        }
</script>

3.属性说明

参数 默认值 类型 说明
type row String 滚动类型:
row:每次滚动一行
continuous:连续滚动
page:整页滚动
isAnimation true Boolean 是否需要动画过渡 (仅 type='row' 和 'page'生效 )
speed 30 [Number, String] 滚动速度,单位:毫秒(仅 type='continuous'生效 )
endDelay 2000 [Number, String] 播放结束后等待多少时间重新播放
singleDuration 300 [Number, String] 单次过度时间,单位:毫秒
singleDelay 3000 [Number, String] 单次等待间隔,单位:毫秒
hoverStep true Boolean 是否允许鼠标hover控制。即鼠标进入停止,移出继续播放
hoverDelay 3000 [Number, String] 鼠标离开时等待多少秒开始播放仅在hoverStep为true是生效 单位:毫秒

其它参数: 参考 el-table(Attributes)

4. 方法

方法名 说明 参数
restart 重新开始

其它方法:参考 el-table(Events)

5. 事件

事件名 说明 参数
complete 单行滚动结束 object

其它事件:参考 el-table(Events)

评论
友情链接