SoFunction
Updated on 2025-04-06

vue-infinite-loading2.0 Chinese document details

Introduction

This is an infinite scrolling plugin used in it, which can help you quickly create an infinite scrolling list.

Features

  1. Mobile support friendly
  2. Compatible with any scrollable element
  3. There are different rotators that can be used as loading animations
  4. Supports displaying results after loading
  5. Supports unlimited loading in both directions

<p >Installation</p>

<strong>Note: vue-infinite-loading2.0 can only be used in Vue.js2.0. If you want to use it in Vue.js1.0, please install vue-infinite-loading1.3 version</strong>

npm install vue-infinite-loading --save

Import method

es6 module import method

import InfiniteLoading from 'vue-infinite-loading';
export default {
 components: {
  InfiniteLoading,
 },
};

CommonJS module import method

const InfiniteLoading = require('vue-infinite-loading');
export default {
 components: {
   InfiniteLoading,
 },
};

Other ways

<script src="/path/to/vue-infinite-loading/dist/"></script>

A global variable VueInfiniteLoading will be registered, and it needs to be used as follows:

 ...
 components: {
   VueInfiniteLoading:,
 }
...

start

Basic use

In this example, we will create a basic infinite list with three steps:

  1. In your template, create a list with v-for
  2. Place the InfiniteLoading component at the bottom of the list;
  3. Set the ref property of the InfiniteLoading component to infiniteLoading because it is used to trigger the event.
  4. Create and bind a load callback function for the InfiniteLoading component.

Template

<template>
 <div>
  <p v-for="item in list">
  Line:
  <span v-text="item"></span>
  </p>
  <infinite-loading :on-infinite="onInfinite" ref="infiniteLoading">  </infinite-loading>
 </div>
</template>

Script

import InfiniteLoading from 'vue-infinite-loading';
export default {
 data() {
  return {
   list: []
  };
 },
 methods: {
  onInfinite() {
   setTimeout(() => {
    const temp = [];
    for (let i =  + 1; i <=  + 20; i++) {
     (i);
    }
     = (temp);
    this.$.$emit('$InfiniteLoading:loaded');
   }, 1000);
  }
 },
 components: {
  InfiniteLoading
 }
};

In the <strong>onInfinite</strong> function, we push 20 numbers into the list array each time. We use <strong>setTimeout</strong> to simulate asynchronous requests. Finally, don't forget to trigger a <strong>$InfiniteLoading:loaded</strong> event, which will tell the <strong>InfiniteLoading</strong> component that the data has been downloaded successfully.

Now, we can display the effect according to the above code.

<p >Example: Hacker News List Page</p>

In this example, we will imitate a hacker news list page, but will use <strong>InfiniteLoading</strong> instead of <strong>pagination</strong>

Before we start this example, we need to prepare the following:

  1. Get the news list API, in this case we useHN Search API
  2. ImportaxiosPlugin to request data

Template

<div class="hacker-news-list">
 <div class="hacker-news-header">
  <a target="_blank" href="/" rel="external nofollow" rel="external nofollow" >
   ![](/)
  </a>
  <span>Hacker News</span>
</div>
<div class="hacker-news-item" v-for="(item, key) in list">
 <span class="num" v-text="key + 1"></span>
 <p>
  <a target="_blank" :href="" rel="external nofollow" rel="external nofollow" v-text=""></a>
 </p>
 <p>
  <small>
   <span v-text=""></span>
   points by
   <a target="_blank" :href="'/user?id=' + " rel="external nofollow" rel="external nofollow" 
    v-text=""></a>
    |
   <a target="_blank" :href="'/item?id=' + " rel="external nofollow" rel="external nofollow" 
    v-text="item.num_comments + ' comments'"></a>
  </small>
 </p>
</div>
 <infinite-loading :on-infinite="onInfinite" ref="infiniteLoading">
 <span slot="no-more">
  There is no more Hacker News :(
 </span>
 </infinite-loading>
</div>

In the template, we create a header and a list for the hacker news list. The <strong>InfiniteLoading</strong> component in this example is somewhat different from the one used in the previous example. We customized the prompt content when there is no more data based on <strong>slot</strong>.

Script

import InfiniteLoading from 'vue-infinite-loading';
import axios from 'axios';
const api = '/api/v1/search_by_date?tags=story';
export default {
 data() {
  return {
   list: []
  };
 },
 methods: {
  onInfinite() {
   (api, {
    params: {
     page:  / 20 + 1
    }
   }).then((res) => {
    if () {
      = ();
     this.$.$emit('$InfiniteLoading:loaded');
     if ( / 20 === 3) {
      this.$.$emit('$InfiniteLoading:complete');
     }
    } else {
     this.$.$emit('$InfiniteLoading:complete');
    }
   });
  }
 },
 components: {
  InfiniteLoading
 }
};

In the <strong>onInfinite</strong> function, we request a page of news and push them into the list array each time. If we request 3 pages of news, the <strong>$InfiniteLoading:complete</strong> event will be triggered to tell the <strong>InfiniteLoading</strong> component, and now there is no more data to load. It will display the prompt content we customize in the template, indicating that there is no more data.

Style

.hacker-news-list .hacker-news-item {
  margin: 10px 0;
  padding: 0 10px 0 32px;
  line-height: 16px;
  font-size: 14px;
}
.hacker-news-list .hacker-news-item .num {
 margin-top: 1px;
 margin-left: -32px;
 float: left;
 width: 32px;
 color: #888;
 text-align: right;
}
.hacker-news-list .hacker-news-item p {
 padding-left: 8px;
 margin: 0;
}
.hacker-news-list .hacker-news-item .num:after {
 content: ".";
}
.hacker-news-list .hacker-news-item p>a {
 color: #333;
 padding-right: 5px;
}
.hacker-news-list .hacker-news-item p a {
 text-decoration: none;
}
.hacker-news-list .hacker-news-item p small, .hacker-news-list .hacker-news-item p small a {
 color: #888;
}

<p > Use with filters</p>

Based on the previous example, we will create a drop-down selection at the head as the filter, and when we change the filter, the list will be reloaded.

Template

<div class="hacker-news-list">
<div class="hacker-news-header">
 <a target="_blank" href="/" rel="external nofollow" rel="external nofollow" >
  ![](/)
 </a>
 <span>Hacker News</span>
 <select v-model="tag" @change="changeFilter()">
  <option value="story">Story</option>
  <option value="poll">Poll</option>
  <option value="show_hn">Show hn</option>
  <option value="ask_hn">Ask hn</option>
  <option value="front_page">Front page</option>
 </select>
</div>
<div class="hacker-news-item" v-for="(item, key) in list">
 <span class="num" v-text="key + 1"></span>
 <p>
  <a target="_blank" :href="" rel="external nofollow" rel="external nofollow" v-text=""></a>
 </p>
 <p>
  <small>
   <span v-text=""></span>
   points by
   <a target="_blank" :href="'/user?id=' + " rel="external nofollow" rel="external nofollow" 
     v-text=""></a>
   |
   <a target="_blank" :href="'/item?id=' + " rel="external nofollow" rel="external nofollow" 
     v-text="item.num_comments + ' comments'"></a>
  </small>
 </p>
</div>
<infinite-loading :on-infinite="onInfinite" ref="infiniteLoading">
 <span slot="no-more">
  There is no more Hacker News :(
 </span>
</infinite-loading>
</div>

Script

import InfiniteLoading from 'vue-infinite-loading';
import axios from 'axios';
const api = '/api/v1/search_by_date';
export default {
 data() {
  return {
   list: [],
   tag: 'story'
  };
 },
 methods: {
  onInfinite() {
   (api, {
    params: {
     tags: ,
     page:  / 20 + 1
    }
   }).then((res) => {
    if () {
      = ();
     this.$.$emit('$InfiniteLoading:loaded');
     if ( / 20 === 10) {
      this.$.$emit('$InfiniteLoading:complete');
     }
    } else {
     this.$.$emit('$InfiniteLoading:complete');
    }
   });
  },
  changeFilter() {
    = [];
   this.$nextTick(() => {
    this.$.$emit('$InfiniteLoading:reset');
   });
  }
 },
 components: {
  InfiniteLoading
 }
};

In the changeFilter function, we understand the list and wait for the DOM to update, and then we trigger a <strong>$InfiniteLoading:reset</strong> event, with the purpose of bringing the <strong>InfiniteLoading</strong> component back to its original state, and it will immediately request new data.

Style

Add styles based on the previous example

.demo-inner {
 margin-left: 20px;
 width: 261px;
 height: 455px;
 border: 1px solid #ccc;
 overflow: auto;
}
.hacker-news-list .hacker-news-header {
  padding: 2px;
  line-height: 14px;
  background-color: #f60;
}
.hacker-news-list {
 min-height: 455px;
 background-color: #f6f6ef;
}
.hacker-news-list .hacker-news-header select {
  float: right;
  color: #fff;
  background-color: transparent;
  border: 1px solid #fff;
  outline: none;
}

<p >Server-side rendering</p>

Server-side rendering (SSR) is a new feature of <strong>Vue.js2.0</strong>. When you use this component in your SSR application, you will get errors like this:

Error: window is not defined
ReferenceError: window is not defined
  at ...
  at ...
  at  (...)
  at Object. (...)
  at p (...)
  at  (...)
  at p (...)
  at Object. (...)
  at p (...)
  at e.__esModule.default (...)

Because <strong>style-loader</strong> does not support local export at this time, please click on the detailshere, so we need the following workaround for your SSR application:

import InfiniteLoading from 'vue-infinite-loading/src/components/';

replace

 import InfiniteLoading from 'vue-infinite-loading';

<strong>npm install less-loader --save-dev</strong> If you haven't installed them yet.

Then your SSR application should run well. If not, you can join thisissueGo to discuss.

<p >Properties<p>

on-infinite

This is a callback function that will be called when scrolling to a specific distance from the bottom of the scrolling parent element.

Usually, after the data is loaded, you should send the <strong>$InfiniteLoading:loaded</strong> event in this function.

- type      Function
- reuqired    true

distance

This is the critical value for rolling. If the distance to the bottom of the scrolling parent element is less than this value, the <strong>on-infinite</strong> callback function will be called.

- type     Number
- required   false
- default   100
- unit     pixel

spinner

With this property, you can choose one of your favorite spinners as the loading animation. Click here to see all available spinners.

- type     String
- required   false
- default   'default'

ref

As you know, this property is an official directive used to get instances of subcomponents. We need to use it to get an instance of the <strong>InfiniteLoading</strong> component to send events. You can get an example in this way: <strong>this.$refs[the value of ref attribute].</strong>

- type   String
- required   true

direction

If you set this property to top, the component will call the on-infinite function when you roll to the top.

<strong>Warning: You must manually set the scrollTop of the scroll parent element to the correct value after the data is loaded, otherwise the component will call the on-infinite function again and again. </strong>

- type     String
- default   'bottom'

<p >Events</p>

The <strong>InfiniteLoading</strong> component will handle the event. If you need to use the <strong>$emit</strong> component instance, you can obtain the component instance through the <strong>ref</strong> attribute.

$InfiniteLoading:loaded

Usually, you need to send this event after the data is loaded, and the <strong>InfiniteLoading</strong> component will hide the loading animation and prepare for the next trigger.

$InfiniteLoading:complete

If the <strong>InfiniteLoading</strong> component will not receive <strong>$InfiniteLoading:loaded</strong>, when you send this event, it will display a prompt without results to the user. If the <strong>InfiniteLoading</strong> component has received <strong>$InfiniteLoading:loaded</strong>, when you send this event, it will display a prompt for the user that there is no more content. You can useslotCustomize what to display.

Your <strong>onInfinite</strong> function might look like this:

onInfinite() {
  this.$(url, (res) => {
  if () {
    = ();
   this.$refs[your ref attirbute's value].$emit('$InfiniteLoading:loaded');
  } else {
   this.$refs[your ref attirbute's value].$emit('$InfiniteLoading:complete');
  }
 });
}

$InfiniteLoading:reset

The <strong>InfiniteLoading</strong> component will return to its original state, and the <strong>on-infinite</strong> function will be called immediately. In most cases, this event is useful if you use this component with a filter or a tab.

<p >Slots</p>

You can use <strong>slot</strong> to customize the content of the prompt, and of course, if you like, you can also use the default content:

 <span slot="{{ slot name }}">
  {{ Your content }}
 </span>

no-results

This content will be displayed when the <strong>InfiniteLoading</strong> component receives the <strong>$InfiniteLoading:complete</strong> event and it has not received the <strong>$InfiniteLoading:loaded</strong> event.

- type    String
- default   No results :(

no-more

This content appears when the <strong>InfiniteLoading</strong> component receives the <strong>$InfiniteLoading:complete</strong> event and it has received the <strong>$InfiniteLoading:loaded</strong> event.

spinner

If, you don't like the current spinner, you can customize your own spinner as the animation when loading.

- type     HTML
- default   default spinner

<p >Spinner</p>

You can use the <strong>spinner</strong> attribute to select your favorite spinner as the loading animation:

<infinite-loading spinner="{{ spinner name }}"></infinite-loading>

ClickhereThere are several available spinners available.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.