Vue implements infinite loading waterfall flow

Vue implements infinite loading waterfall flow

This article example shares the specific code of Vue to achieve infinite loading waterfall flow for your reference. The specific content is as follows

The waterfall flow I made is placed in a nested page, which is similar to the main content of the management background. If you want to change it to full screen, it is also very convenient. In fact, it is easier because it avoids some pitfalls of using onScroll on elements.

Through this waterfall flow, you can master the following knowledge points:

1. Listening to scroll events on elements is a little more troublesome than listening directly on window;
2. image.onload event;
3. promiseAll;
4. Vue's transition-group

Here, mockjs is used to simulate the image data, and then the image data is called through axios. Other data sources can also be used.

By calculating the image height, determine which column to load the image into.
If there is still room on the screen, continue loading.
Infinite scroll loading.
Screen resizing has not been done, but it can be added later.

Paste the code directly, if you have any questions, please feel free to discuss.

<template>
  <div class="waterfall wf-wrap" ref="waterfall" @scroll="onScroll">
    <ul>
      <transition-group name="list" tag="li">
        <li
          v-for="(item,index) in waterfallList"
          :key="index"
          class="wf-item"
          :style="{top:item.top+ 'px',left:item.left+'px', width:item.width+'px', height:item.height + 'px'}"
        >
          <img :src="item.src" />
        </li>
      </transition-group>
    </ul>
  </div>
</template>
<script>
import { getList } from "@/api/demo";

export default {
  name: "Waterfall",
  data() {
    return {
      waterfallList: [],

      waterfallCol: 5,
      colWidth: 236,
      marginRight: 10,
      marginBottom: 10,
      colHeights: [],

      listQuery: {
        page: 1,
        limit: 5,
        sort: "+id"
      },
      loading: false,
      show: true
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      // When initialized, the height of each column is 0
      this.colHeights = new Array(this.waterfallCol);
      for (let i = 0; i < this.colHeights.length; i++) {
        this.colHeights[i] = 0;
      }
      this.colWidth =
        (this.$refs.waterfall.clientWidth -
          (this.waterfallCol - 1) * this.marginRight) /
        this.waterfallCol;
      this.loadImgs();
    },

    loadImgs() {
      this.loading = true;
      // Get data from the api getList(this.listQuery).then(res => {
        let images = res.data.items;
        let promiseAll = [],
          imgs = [],
          total = images.length;

        for (let i = 0; i < total; i++) {
          promiseAll[i] = new Promise(resolve => {
            imgs[i] = new Image();
            imgs[i].src = images[i].image_uri;
            imgs[i].onload = () => {
              let imgData = {};
              imgData.height = (imgs[i].height * this.colWidth) / imgs[i].width;
              imgData.width = this.colWidth;
              imgData.src = images[i].image_uri;
              this.waterfallList.push(imgData);
              this.rankImgs(imgData);
              resolve(imgs[i]);
            };
          });
        }
        Promise.all(promiseAll).then(() => {
          this.loading = false;
          this.loadMore();
        });
      });
    },

    loadMore() {
      if (
        this.$refs.waterfall.clientHeight + this.$refs.waterfall.scrollTop >
          this.filterMin().minHeight &&
        this.loading == false
      ) {
        this.loading = true;
        setTimeout(() => {
          this.loadImgs();
        }, 200);
      }
    },

    rankImgs(imgData) {
      let min = this.filterMin();
      imgData.top = min.minHeight;
      imgData.left = min.minIndex * (this.colWidth + this.marginRight);

      this.colHeights[min.minIndex] += imgData.height + this.marginBottom;
    },

    filterMin() {
      let minHeight = Math.min.apply(null, this.colHeights);
      return {
        minHeight: minHeight,
        minIndex: this.colHeights.indexOf(minHeight)
      };
    },

    onScroll() {
      this.loadMore();
    }
  }
};
</script>

<style lang="scss" scoped>
ul li {
  list-style: none;
}

.wf-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: scroll;
}
.wf-item {
  position: absolute;
}
.wf-item img {
  width: 100%;
  height: 100%;
}
.list-enter-active,
.list-leave-active {
  transition: all 1s;
}
.list-enter, .list-leave-to
/* .list-leave-active for below version 2.1.8 */ {
  opacity: 0;
  transform: translateY(30px);
}
</style>

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Vue implements waterfall flow component sliding to load more
  • Vue waterfall flow component realizes pull-up loading more
  • Vue implements simple waterfall flow layout
  • Vue implements network picture waterfall flow + pull down to refresh + pull up to load more (detailed steps)
  • Write a waterfall plug-in code example through vue
  • Example of using Vue waterfall plugin
  • vue.js component vue-waterfall-easy realizes waterfall flow effect

<<:  Non-standard implementation code for MySQL UPDATE statement

>>:  Detailed explanation of four solutions for implementing in-line scrolling on mobile devices

Recommend

Detailed analysis of MySQL instance crash cases

[Problem description] Our production environment ...

Analysis of the process of simply deploying nginx in Docker container

1. Deploy nginx service in container The centos:7...

How to use mysql to complete the data generation in excel

Excel is the most commonly used tool for data ana...

Solution to the inaccessibility of Tencent Cloud Server Tomcat port

I recently configured a server using Tencent Clou...

MySQL scheduled task implementation and usage examples

This article uses examples to illustrate the impl...

Use of Linux dynamic link library

Compared with ordinary programs, dynamic link lib...

The process of deploying and running countly-server in docker in win10

I have just come into contact with and become fam...

Using react+redux to implement counter function and problems encountered

Redux is a simple state manager. We will not trac...

How to install OpenSuse on virtualbox

The virtual machine is installed on the host mach...

jQuery plugin to implement accordion secondary menu

This article uses a jQuery plug-in to create an a...

MySQL partition table is classified by month

Table of contents Create a table View the databas...

Detailed explanation of the 14 common HTTP status codes returned by the server

HTTP Status Codes The status code is composed of ...

HTML set as homepage and add to favorites_Powernode Java Academy

How to implement the "Set as homepage" ...

W3C Tutorial (14): W3C RDF and OWL Activities

RDF and OWL are two important semantic web techno...