Introduction
This is an infinite scrolling plugin used in it, which can help you quickly create an infinite scrolling list.
Features
- Mobile support friendly
- Compatible with any scrollable element
- There are different rotators that can be used as loading animations
- Supports displaying results after loading
- 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:
- In your template, create a list with v-for
- Place the InfiniteLoading component at the bottom of the list;
- Set the ref property of the InfiniteLoading component to infiniteLoading because it is used to trigger the event.
- 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:
- Get the news list API, in this case we useHN Search API
- 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.