The way vue realizes the automatic scrolling of the list (2)

        Continuing from the content of the previous chapter, the topic this time is to use Vue to achieve smooth scrolling with intervals in the list.

        So as usual, let's analyze the problem first. Still taking scrolling up as an example, the list scrolls one row every three seconds. Regardless of the smoothness issue, if you just let the list scroll up one line every three seconds, this is actually very simple. You have guessed it. According to my habit, I still use a timer to solve it.

        Set the timer, every three seconds, let the list move up the height of one row, and then when the last piece of data appears, after the next three seconds, it will return to the initial state.

        Here is the code implementation described above:

    tableTimerFun() {
      var count = 0;  //每滚动一次,count加1
      //tableList是列表的数据对象,maxCanSee代表可视范围内的最大完整数据条数
      if (this.tableList.length > this.maxCanSee) {  
        this.tableTimer = setInterval(() => {
          //如果还没滚动到最后一条数据,则列表向上移动以上的高度
          if (count < this.tableList.length - this.maxCanSee) { 
            this.tableTop -= this.tableLineHeight;   //tableLineHeight代表列表中一行的高度
            count++;   //每滚动一次,count加1
          } else {   //如果滚动到最后一条,则恢复初始状态
            count = 0;
            this.tableTop = 0;
          }
        }, 3000);
      }
    },

        The above content has realized the scrolling of the list at intervals, and the next step is to solve the problem of smoothness. This time we don't let the list scroll up by 1 pixel every 0.1s like in the previous chapter, and use high-frequency displacement to create a smooth moving visual effect. This time we will handle it directly with css.

        There is a very useful dynamic style transition in css, which allows the rendered object to change smoothly when its position, size, etc. change. So we directly let the container of the list get the following styles:

transition: all 0.5s;

        If you are lazy, you can write all directly. If you have specific needs or only allow a certain style to change smoothly, you should read the official documentation. I won’t explain much here. 0.5s is the change time.

        So far, using Vue to realize the smooth scrolling of the list with intervals has actually been realized, but there is still a flaw, that is, when the last piece of data appears and the initial state is reset, the list will quickly scroll to the head of the list. In fact, it is not difficult to understand. According to the above writing method, the normal situation is to move up the height of one line, but when the last one is reset to the initial state, it moves close to the height of the entire list. So you will see the list scroll quickly during this process. It is said to be a defect but it is not a defect, depending on the specific needs. There is a solution, which will be discussed in the next article.

        The rest is actually to consider the lack of data in the development of large data screens. For example, there are at most 6 items in the list within the visible range, but only 3 items are displayed in the interface. At this time, the list does not need to be scrolled in real time. , I will talk about this later, but there are in the complete code below, if you are interested, you can learn about it in advance.

        The following is the complete code, or the same sentence: Paste the following code directly and run it will not run successfully, because the following complete code involves interface calls, but all functions have been completed in one step, I hope you can understand more through comments , rather than simply copy and paste. hope it is of help to you.

<template>
  <div class="orderProcess">
    <div class="loading_div" v-show="!showFlag">
      <!-- Loading样式自己写,不需要,直接删除即可 -->
      <div>Loading...</div>
    </div>
    <div class="success_info_body" v-show="showFlag">
      <div class="table_head">
        <div class="tr1 tr">订单号</div>
        <div class="tr2 tr">项目名称</div>
        <div class="tr3 tr">需求方量</div>
        <div class="tr4 tr">预交付日期</div>
        <div class="tr5 tr">进度</div>
      </div>
      <div class="table_body">
        <!-- tableTop随时间推移不对增减,即列表不断往上 -->
        <div class="table_list" :style="{top: tableTop + 'px'}"> 
          <div
            class="tr_div"
            v-for="(item,index) in tableList"
            :key="index"
            :class="{'exception_style_tr':item.overDays>6 && item.process < 100}"
          >
            <div
              class="tr1 tr"
              :class="{'exception_style':item.overDays>6 && item.process < 100, 'notice_style':item.overDays>0 && item.overDays<7 && item.process < 100}"
            >{
   
   {item.orderNo}}</div>
            <div
              class="tr2 tr"
              :class="{'exception_style':item.overDays>6 && item.process < 100, 'notice_style':item.overDays>0 && item.overDays<7 && item.process < 100}"
            >{
   
   {item.projectName}}</div>
            <div
              class="tr3 tr"
              :class="{'exception_style':item.overDays>6 && item.process < 100, 'notice_style':item.overDays>0 && item.overDays<7 && item.process < 100}"
              v-if="item.needVol!='-'&&item.needVol!='无法计算'"
            >{
   
   {Number(item.needVol).toFixed(3)}} m³</div>
            <div
              class="tr3 tr"
              :class="{'exception_style':item.overDays>6 && item.process < 100, 'notice_style':item.overDays>0 && item.overDays<7 && item.process < 100}"
              v-else
            >-</div>
            <div
              class="tr4 tr"
              :class="{'exception_style':item.overDays>6 && item.process < 100, 'notice_style':item.overDays>0 && item.overDays<7 && item.process < 100}"
            >{
   
   {item.completeDate}}</div>
            <div
              class="tr5 tr"
              :class="{'exception_style':item.overDays>6 && item.process < 100, 'notice_style':item.overDays>0 && item.overDays<7 && item.process < 100}"
              v-if="item.process!='-'"
            >{
   
   {Number(item.process).toFixed(2)}} %</div>
            <div
              class="tr5 tr"
              :class="{'exception_style':item.overDays>6 && item.process < 100, 'notice_style':item.overDays>0 && item.overDays<7 && item.process < 100}"
              v-else
            >-</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableTimer: null,
      tableTop: 0,  //列表向上移动的像素
      tableList: [], //tableList是列表的数据对象
      showFlag: false,
      componentTimer: null,
      maxCanSee: 6, //maxCanSee代表可视范围内的最大完整数据条数
      tableLineHeight: 45   //tableLineHeight代表列表中一行的高度
    };
  },
  props: ["activeFactoryId"],
  watch: {
    activeFactoryId(val, oldVal) {
      clearInterval(this.componentTimer);
      this.bsGetOrderProcessList();
      this.componentTimerFun();
    }
  },
  beforeDestroy() {
    clearInterval(this.componentTimer);
    clearInterval(this.tableTimer);
  },
  mounted() {
 
  },
  methods: {
    bsGetOrderProcessList() {
      clearInterval(this.tableTimer);
      this.tableTop = 0;
      if (this.activeFactoryId != "") {
        this.showFlag = false;
        this.$ajax({
          method: "get",
          url: ``  //接口地址,不公开
        })
          .then(res => {
            this.tableList = res.data.data;
            this.showFlag = true;
            this.actionFun();
          })
          .catch(function(err) {
            console.log("bsGetOrderProcessList error!");
          });
      }
    },
    actionFun() {
      if (this.tableList.length > 6) {
        this.tableTimerFun();
      } else {
        this.fillTableList();
      }
      this.showFlag = true;
    },
    fillTableList() {
      var addLength = this.maxCanSee - this.tableList.length;
      for (var i = 0; i < addLength; i++) {
        this.tableList.push({
          orderNo: "-",
          projectName: "-",
          needVol: "-",
          completeDate: "-",
          process: "-"
        });
      }
    },
    tableTimerFun() {
      var count = 0;  //每滚动一次,count加1
      if (this.tableList.length > this.maxCanSee) {  //tableList是列表的数据对象,maxCanSee代表可视范围内的最大完整数据条数
        this.tableTimer = setInterval(() => {
          if (count < this.tableList.length - this.maxCanSee) { //如果还没滚动到最后一条数据,则列表向上移动以上的高度
            this.tableTop -= this.tableLineHeight;   //tableLineHeight代表列表中一行的高度
            count++;   //每滚动一次,count加1
          } else {   //如果滚动到最后一条,则恢复初始状态
            count = 0;
            this.tableTop = 0;
          }
        }, 3000);
      }
    },
    componentTimerFun() {
      this.componentTimer = setInterval(() => {
        this.bsGetOrderProcessList();
      }, 3600000);
    }
  }
};
</script>

<style scoped>
.orderProcess {
  width: 600px;
  height: 313px;
}
.loading_div {
  color: #eee;
  padding-top: 100px;
}
.table_head {
  width: 100%;
  height: 30px;
  line-height: 30px;
  background: rgba(90, 127, 200, 0.5);
  display: flex;
  color: #eee;
  text-align: center;
  font-size: 15px;
}
.tr1 {
  width: 25%;
}
.tr2 {
  width: 25%;
}
.tr3 {
  width: 18%;
}

.tr4 {
  width: 18%;
}
.tr5 {
  flex: 1;
}
.tr {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  box-sizing: border-box;
  padding: 0 5px;
  text-align: center;
  font-size: 14px;
}

.table_body {
  width: 100%;
  height: 270px;
  overflow: hidden;
  position: relative;
}

.table_list {
  width: 100%;
  position: absolute;
  transition: all 0.5s;
}

.tr_div {
  width: 100%;
  display: flex;
  color: #eee;
  text-align: center;
  line-height: 45px;
  font-size: 13px;
}
.exception_style_tr {
  animation: exception_style_tr 0.8s linear;
  -moz-animation: exception_style_tr 0.8s linear;
  -webkit-animation: exception_style_tr 0.8s linear;
  -o-animation: exception_style_tr 0.8s linear;
  animation-iteration-count: infinite;
  -webkit-animation-iteration-count: infinite;
}
@keyframes exception_style_tr {
  0% {
    background: rgba(3, 145, 167, 0.1);
  }
  50% {
    background: rgba(250, 4, 4, 0.15);
  }
  100% {
    background: rgba(3, 145, 167, 0.1);
  }
}

@-moz-keyframes exception_style_tr {
  0% {
    background: rgba(3, 145, 167, 0.1);
  }
  50% {
    background: rgba(250, 4, 4, 0.15);
  }
  100% {
    background: rgba(3, 145, 167, 0.1);
  }
}
@-webkit-keyframes exception_style_tr {
  0% {
    background: rgba(3, 145, 167, 0.1);
  }
  50% {
    background: rgba(250, 4, 4, 0.15);
  }
  100% {
    background: rgba(3, 145, 167, 0.1);
  }
}
@-o-keyframes exception_style_tr {
  0% {
    background: rgba(3, 145, 167, 0.1);
  }
  50% {
    background: rgba(250, 4, 4, 0.15);
  }
  100% {
    background: rgba(3, 145, 167, 0.1);
  }
}
.exception_style {
  font-weight: bold;
  animation: exception_style 0.8s linear;
  -moz-animation: exception_style 0.8s linear;
  -webkit-animation: exception_style 0.8s linear;
  -o-animation: exception_style 0.8s linear;
  animation-iteration-count: infinite;
  -webkit-animation-iteration-count: infinite;
}
@keyframes exception_style {
  0% {
    color: #eee;
  }
  50% {
    color: #fa0404;
  }
  100% {
    color: #eee;
  }
}

@-moz-keyframes exception_style {
  0% {
    color: #eee;
  }
  50% {
    color: #fa0404;
  }
  100% {
    color: #eee;
  }
}
@-webkit-keyframes exception_style {
  0% {
    color: #eee;
  }
  50% {
    color: #fa0404;
  }
  100% {
    color: #eee;
  }
}
@-o-keyframes exception_style {
  0% {
    color: #eee;
  }
  50% {
    color: #fa0404;
  }
  100% {
    color: #eee;
  }
}
.notice_style {
  font-weight: bold;
  color: #d1ce02;
}

</style>

        Finally, the effect video:

Guess you like

Origin blog.csdn.net/zxczero/article/details/126104905