Vue implements table automatic scrolling

Customer demand: Automatic scrolling of the table in the lower right cornerInsert image description here

In this case, no third-party plug-ins are used, and all are implemented using the relevant js, css and timer methods in vue.

The first step in solving a problem is not to find the code, but to analyze the problem. There are two common methods for automatic scrolling of lists (scrolling up, down, left, and right is not described in detail, it is just a matter of direction. In this case, automatic scrolling upward is used as an example): (1) constant speed scrolling (2) smooth scrolling with intervals. This case first gives a plan for rolling at a constant speed.

To scroll upward at a constant speed, in my experience, the easiest thing to think of is to use a timer. Every other time difference, the list moves upward by one pixel (larger than one pixel may visually give people the feeling of stuck and dropped frames). As long as the time is short enough, it will give people a feeling of moving upward at a constant speed. Then we need to consider the problem of list connection. No matter how long the list is, there will be an end. We need to consider the problem of scrolling to the last piece of data.

The plan I gave is to splice a list with the same content at the end of the list to form a list twice the length of the original list (if you consider performance issues, just splice the first few data of the original list after the original list. Specific items It is determined based on the maximum number of complete data items within the scrolling visible range (you will understand it as you read below), and then when the splicing list scrolls to the visible range, the content is consistent with the initial state (that is, the content of the first half of the splicing list When the last record scrolls up until it disappears completely), reset the distance of scrolling up the spliced ​​list to zero, which can visually give people a feeling of a constant upward speed and an infinite loop.

Let’s start with the code for the timer method.

//根据列表长度是否超过可视范围内能够显示的最大完整数据条数,来控制列表是否需要滚动
tableActionFun() {
    
    
      this.tableListSize = this.tableList.length;
      //下面的visibleSize是可视范围内能够显示的最大完整数据条数
      if (this.tableListSize > this.visibleSize) {
    
    
        this.tableList = this.tableList.concat(this.tableList);
        this.tableTimerFun();  //列表滚动方法
      }
},
 
//列表滚动方法
tableTimerFun() {
    
    
      var count = 0;
      this.tableTimer = setInterval(() => {
    
    
        if (count < (this.tableList.length / 2) * this.lineHeight) {
    
    
          this.tableTop -= 1;
          count++;
        } else {
    
    
          count = 0;
          this.tableTop = 0;
        }
      }, this.tableTimerInterval);
},

The above code snippet mentions visibleSize, the maximum number of complete data items that can be displayed within the visual range. Just look at the screenshot in the case and you will understand it at a glance. As can be seen in the screenshot, the first and last pieces of data are not fully displayed because their parts beyond the parent container are overflow: hidden, so the visibleSize = 6 in the case.

Therefore, in this case, the list is automatically and quickly scrolled by continuously moving the list up, and the parent container hides the excess parts. There may be some omissions during the explanation. Please upload the complete code directly, with comments on the important parts. Directly pasting and running the code below will not run successfully, because the complete code below involves interface calls, but all functions are in place in one step. I hope you can understand more through comments instead of simply copying and pasting. hope it is of help to you.

<template>
    <div class="productProcess">
        <!-- 如果页面刷新数据比较频繁,可以将loading、showFlag的相关代码删除,防止过于频繁的出现加载动画 -->
        <div class="loading_div" v-show="!showFlag">
            <div>Loading...</div>  <!-- 这个loading自己写,代码没贴出来 -->
        </div>
        <div class="success_info_body" v-show="showFlag">
            <!-- 参数名称、列数根据实际情况调整 -->
            <div class="table_body">
                <div class="table_th">
                    <div class="tr1 th_style">排产编号</div>
                    <div class="tr2 th_style">类型</div>
                    <div class="tr3 th_style">日期</div>
                    <div class="tr4 th_style">进度</div>
                </div>
                <div class="table_main_body">
                    <div class="table_inner_body" :style="{top: tableTop + 'px'}">
                        <div class="table_tr" v-for="(item,index) in tableList" :key="index">
                            <div class="tr1 tr">{
   
   {item.planNo}}</div>
                            <div class="tr2 tr">{
   
   {item.type}}</div>
                            <div class="tr3 tr" v-if="item.startDate!='-'">{
   
   {item.startDate}} ~ {
   
   {item.endDate}}</div>
                            <div class="tr3 tr" v-else>-</div>
                            <div class="tr4 tr" v-if="item.process!='-'">{
   
   {Number(item.process).toFixed(2)}} %</div>
                            <div class="tr4 tr" v-else>-</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
 
 <script>
    export default {
      
      
        data() {
      
      
            return {
      
      
                showFlag: true,
                tableTimer: null,
                tableTop: 0,
                tableList: [
                    {
      
      
                        "process": 0.0000,
                        "planNo": "BP2022060701",
                        "endDate": "2022-06-07",
                        "type": "砌块",
                        "startDate": "2022-06-07"
                    },
                    {
      
      
                        "process": 0.0000,
                        "planNo": "BP2022060701",
                        "endDate": "2022-06-07",
                        "type": "砌块",
                        "startDate": "2022-06-07"
                    },
                    {
      
      
                        "process": 0.0000,
                        "planNo": "BP2022060701",
                        "endDate": "2022-06-07",
                        "type": "砌块",
                        "startDate": "2022-06-07"
                    },
                    {
      
      
                        "process": 0.0000,
                        "planNo": "BP2022060701",
                        "endDate": "2022-06-07",
                        "type": "砌块",
                        "startDate": "2022-06-07"
                    },
                    {
      
      
                        "process": 0.0000,
                        "planNo": "BP2022060701",
                        "endDate": "2022-06-07",
                        "type": "砌块",
                        "startDate": "2022-06-07"
                    },
                    {
      
      
                        "process": 0.0000,
                        "planNo": "WP2022061301",
                        "endDate": "2022-06-13",
                        "type": "墙板",
                        "startDate": "2022-06-13"
                    }
                ],
                
                tableListSize: 0,
                componentTimer: null,

                //需要根据情况设置的参数
                title: "排产进度",
                visibleSize: 2, //容器内可视最大完整行数
                lineHeight: 49, //每行的实际高度(包含margin-top/bottom,border等)
                componentTimerInterval: 3600000, //刷新数据的时间间隔
                tableTimerInterval: 200 //向上滚动 1px 所需要的时间,越小越快,推荐值 100
            };
        },
        mounted() {
      
      
            clearInterval(this.componentTimer);
            this.bsGetProductProcess();
            this.componentTimerFun();
        },
        methods: {
      
      
            //调用数据接口,获取列表数据,根据自己情况填接口url
            bsGetProductProcess() {
      
      
                clearInterval(this.tableTimer);
                this.tableTop = 0;
                this.showFlag = true;
                this.tableActionFun();
            },

            tableActionFun() {
      
      
                this.tableListSize = this.tableList.length;
                if (this.tableListSize > this.visibleSize) {
      
      
                    this.tableList = this.tableList.concat(this.tableList);
                    this.tableTimerFun();
                } else {
      
      
                    //this.fillTableList();
                }
            },
            //当数据过少时,不触发自动轮播事件,并填充没有数据的行,参数根据实际情况修改即可
            fillTableList() {
      
      
                var addLength = this.visibleSize - this.tableListSize;
                for (var i = 0; i < addLength; i++) {
      
      
                    this.tableList.push({
      
      
                        planNo: "-",
                        type: "-",
                        startDate: "-",
                        endDate: "-",
                        process: "-"
                    });
                }
            },
            tableTimerFun() {
      
      
                var count = 0;
                this.tableTimer = setInterval(() => {
      
      
                    if (count < (this.tableList.length / 2) * this.lineHeight) {
      
      
                        this.tableTop -= 1;
                        count++;
                    } else {
      
      
                        count = 0;
                        this.tableTop = 0;
                    }
                }, this.tableTimerInterval);
            },
            componentTimerFun() {
      
       //页面自动刷新时间
                this.componentTimer = setInterval(() => {
      
      
                    this.bsGetProductProcess();
                }, this.componentTimerInterval);
            }
        },
        beforeDestroy() {
      
      
            clearInterval(this.componentTimer);
            clearInterval(this.tableTimer);
        },
    }
</script>

<style scoped>
.productProcess {
      
      
  width: 550px;
  height: 415px;
}
.loading_div {
      
      
  color: #eee;
  padding-top: 100px;
}
.title_div {
      
      
  width: 100%;
}
.table_body {
      
      
  width: 100%;
  margin-top: 15px;
}
.table_th {
      
      
  width: 100%;
  display: flex;
  height: 40px;
  line-height: 40px;
}
.tr {
      
      
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  box-sizing: border-box;
  padding: 0 5px;
  text-align: center;
  font-size: 14px;
}
.tr1 {
      
      
  width: 28%;
}
.tr2 {
      
      
  width: 15%;
}
.tr3 {
      
      
  width: 35%;
  font-size: 13px;
}
 
.tr4 {
      
      
  flex: 1;
}
 
.th_style {
      
      
  color: rgb(0, 221, 253);
  font-weight: bold;
  font-size: 18px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  box-sizing: border-box;
  padding: 0 5px;
  text-align: center;
}
.table_main_body {
      
      
  width: 100%;
  height: 294px;
  overflow: hidden;
  position: relative;
}
.table_inner_body {
      
      
  width: 100%;
  position: absolute;
  left: 0;
}
.table_tr {
      
      
  display: flex;
  height: 40px;
  line-height: 40px;
  color: #eee;
  font-size: 15px;
  background: rgba(3, 145, 167, 0.1);
  border: 1px solid rgb(4, 114, 131);
  margin-top: 7px;
}
</style>

Finally, there is the effects video.

Large screen billboard-table self-scrolling effect

Original link: https://blog.csdn.net/zxczero/article/details/125613915

Guess you like

Origin blog.csdn.net/weixin_43361722/article/details/131168905