您好,登錄后才能下訂單哦!
簡介
這是一個使用在Vue.js中的無限滾動插件,它可以幫助你快速創建一個無限滾動列表。
特點
<p id="installation">安裝</p>
<strong>注意:vue-infinite-loading2.0只能在Vue.js2.0中使用。如果你想在Vue.js1.0中使用,請安裝vue-infinite-loading1.3版本</strong>
npm install vue-infinite-loading --save
導入方式
es6模塊導入方式
import InfiniteLoading from 'vue-infinite-loading'; export default { components: { InfiniteLoading, }, };
CommonJS 模塊導入方式
const InfiniteLoading = require('vue-infinite-loading'); export default { components: { InfiniteLoading, }, };
其他方式
<script src="/path/to/vue-infinite-loading/dist/vue-infinite-loading.js"></script>
vue-infinite-loading.js會注冊一個全局變量VueInfiniteLoading,使用時需要這樣:
... components: { VueInfiniteLoading:VueInfiniteLoading.default, } ...
開始
基礎使用
在本例中,我們將創建一個基本的無限列表,有如下三個步驟:
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 = this.list.length + 1; i <= this.list.length + 20; i++) { temp.push(i); } this.list = this.list.concat(temp); this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded'); }, 1000); } }, components: { InfiniteLoading } };
在<strong>onInfinite</strong>函數中,每次我們都push 20 個數字到list數組中。我們使用<strong>setTimeout</strong>來模擬異步請求。最后,不要忘了觸發一個<strong>$InfiniteLoading:loaded</strong>事件,它將告訴<strong>InfiniteLoading</strong>組件,數據已經下載成功。
現在,我們可以根據上面的代碼,來顯示效果。
<p id="hacker">例子:黑客新聞列表頁面</p>
在這個例子中,我們將模仿一個黑客新聞列表頁面,但是會用<strong>InfiniteLoading</strong>代替<strong>分頁</strong>
在開始這個例子之前,我們需要準備以下內容:
Template
<div class="hacker-news-list"> <div class="hacker-news-header"> <a target="_blank" rel="external nofollow" rel="external nofollow" > ![](https://cache.yisu.com/upload/information/20200622/114/44427.gif) </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="item.url" rel="external nofollow" rel="external nofollow" v-text="item.title"></a> </p> <p> <small> <span v-text="item.points"></span> points by <a target="_blank" :href="'https://news.ycombinator.com/user?id=' + item.author" rel="external nofollow" rel="external nofollow" v-text="item.author"></a> | <a target="_blank" :href="'https://news.ycombinator.com/item?id=' + item.objectID" 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>
在模板中,我們為黑客新聞列表創建了一個header 和 一個list 。在這個例子中的<strong>InfiniteLoading</strong>組件,與上個例子中使用方式有些不同。我們基于<strong>slot</strong>自定義了當沒有更多數據時的提示內容。
Script
import InfiniteLoading from 'vue-infinite-loading'; import axios from 'axios'; const api = 'http://hn.algolia.com/api/v1/search_by_date?tags=story'; export default { data() { return { list: [] }; }, methods: { onInfinite() { axios.get(api, { params: { page: this.list.length / 20 + 1 } }).then((res) => { if (res.data.hits.length) { this.list = this.list.concat(res.data.hits); this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded'); if (this.list.length / 20 === 3) { this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete'); } } else { this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete'); } }); } }, components: { InfiniteLoading } };
在<strong>onInfinite</strong>函數中,我們請求了一頁的新聞,并且每次將它們推入到list數組中。如果我們請求了3頁新聞,將觸發 <strong>$InfiniteLoading:complete</strong>事件去告訴<strong>InfiniteLoading</strong>組件,現在已經沒有更多數據可以加載了。它將顯示我們自定義在模板中的,表示沒有更多數據的提示內容。
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 id="use">與過濾器一塊使用</p>
在上個例子的基礎上,我們將在頭部創建一個下拉選擇作為過濾器,當我們改變過濾器,列表將會重新加載。
Template
<div class="hacker-news-list"> <div class="hacker-news-header"> <a target="_blank" rel="external nofollow" rel="external nofollow" > ![](https://cache.yisu.com/upload/information/20200622/114/44427.gif) </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="item.url" rel="external nofollow" rel="external nofollow" v-text="item.title"></a> </p> <p> <small> <span v-text="item.points"></span> points by <a target="_blank" :href="'https://news.ycombinator.com/user?id=' + item.author" rel="external nofollow" rel="external nofollow" v-text="item.author"></a> | <a target="_blank" :href="'https://news.ycombinator.com/item?id=' + item.objectID" 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 = 'http://hn.algolia.com/api/v1/search_by_date'; export default { data() { return { list: [], tag: 'story' }; }, methods: { onInfinite() { axios.get(api, { params: { tags: this.tag, page: this.list.length / 20 + 1 } }).then((res) => { if (res.data.hits.length) { this.list = this.list.concat(res.data.hits); this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded'); if (this.list.length / 20 === 10) { this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete'); } } else { this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete'); } }); }, changeFilter() { this.list = []; this.$nextTick(() => { this.$refs.infiniteLoading.$emit('$InfiniteLoading:reset'); }); } }, components: { InfiniteLoading } };
在<strong>changeFilter</strong>函數中,我們清楚了列表并等待DOM更新,然后我們觸發一個<strong>$InfiniteLoading:reset</strong>事件,目的是讓<strong> InfiniteLoading </strong>組件回到最初狀態,它將立刻請求新的數據。
Style
在上個例子基礎上增加樣式
.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 id="server">服務端渲染</p>
服務端渲染(SSR)是<strong>Vue.js2.0</strong>的新特性,當你在你的SSR應用中使用這個組件,會得到類似這樣的錯誤:
Error: window is not defined ReferenceError: window is not defined at ... at ... at e.exports (...) at Object. (...) at p (...) at Object.e.exports.render.e (...) at p (...) at Object. (...) at p (...) at e.__esModule.default (...)
因為<strong>style-loader</strong>不支持在這個時候本地導出,詳情點這里,所以我們需要下面的變通方案,為了你的SSR應用:
import InfiniteLoading from 'vue-infinite-loading/src/components/Infiniteloading.vue';
代替
import InfiniteLoading from 'vue-infinite-loading';
<strong>npm install less less-loader --save-dev</strong> 如果你還沒有安裝它們。
然后你的SSR應用應該運行良好。如果不是,你可以加入這個issue去討論。
<p id="properties">屬性<p>
on-infinite
這是一個回調函數,當滾動到距離滾動父元素底部特定距離的時候,會被調用。
通常,在數據加載完成后,你應該在這個函數中發送<strong>$InfiniteLoading:loaded</strong>事件。
- type Function - reuqired true
distance
這是滾動的臨界值。如果到滾動父元素的底部距離小于這個值,那么<strong>on-infinite</strong>回調函數就會被調用。
- type Number - required false - default 100 - unit pixel
spinner
通過這個屬性,你可以選擇一個你最喜愛旋轉器作為加載動畫。點擊這里可以看到所有可用的旋轉器。
- type String - required false - default 'default'
ref
正如你所知,這個屬性是一個Vue.js的官方指令,用來獲取子組件的實例。我們需要用它來得到<strong> InfiniteLoading </strong>組件的實例來發送事件。你可以用這種方式來得到實例:<strong>this.$refs[the value of ref attribute].</strong>
- type String - required true
direction
如果你設置這個屬性為top,那么這個組件將在你滾到頂部的時候,調用on-infinite函數。
<strong>警告:你必須在數據加載后,手動地將滾動父元素的scrollTop設置為正確的值,否則,該組件會一次又一次調用on-infinite函數。</strong>
- type String - default 'bottom'
<p id="event">事件</p>
<strong>InfiniteLoading </strong>組件將處理一下事件。如果你需要通過組件的實例來<strong>$emit</strong>,則可以通過<strong>ref</strong>屬性來得到組件實例。
$InfiniteLoading:loaded
通常,你需要在數據加載后發送這個事件,<strong> InfiniteLoading</strong>組件將隱藏加載動畫,并且準備下一次觸發。
$InfiniteLoading:complete
如果<strong>InfiniteLoading</strong>組件就不會接收<strong>$InfiniteLoading:loaded</strong>,當你發送這個事件后,它將為用戶顯示一個沒有結果的提示。如果<strong>InfiniteLoading</strong>組件接收過<strong>$InfiniteLoading:loaded</strong>,當你發送這個事件的時候,它會為用戶顯示一個沒有更多內容的提示。你可以利用slot來自定義需要顯示的內容。
你的<strong>onInfinite</strong>函數可能像這個樣子:
onInfinite() { this.$http.get(url, (res) => { if (res.data) { this.list = this.list.concat(res.data); this.$refs[your ref attirbute's value].$emit('$InfiniteLoading:loaded'); } else { this.$refs[your ref attirbute's value].$emit('$InfiniteLoading:complete'); } }); }
$InfiniteLoading:reset
<strong>InfiniteLoading</strong>組件將會回到最初的狀態,并且<strong>on-infinite</strong>函數將會立刻被調用。大部分情況下,如果你把這個組件同過濾器或制表符一起使用,這個事件還是有用的。
<p id="slots">插槽</p>
你可以利用<strong>slot</strong>自定義提示的內容,當然,如果你喜歡的話,也可以使用默認內容:
<span slot="{{ slot name }}"> {{ Your content }} </span>
no-results
當<strong>InfiniteLoading</strong>組件接收到<strong>$InfiniteLoading:complete </strong>事件并且它沒有接收過<strong>$InfiniteLoading:loaded</strong>事件時,這個內容會顯示出來。
- type String - default No results :(
no-more
當<strong>InfiniteLoading</strong>組件接收到<strong>$InfiniteLoading:complete </strong>事件并且它已經接收過<strong>$InfiniteLoading:loaded</strong>事件時,這個內容會出現。
spinner
如果,你不喜歡當前旋轉器,你可以自定義自己的旋轉器作為加載時的動畫。
- type HTML - default default spinner
<p id="spinners">旋轉器</p>
你可以用<strong>spinner</strong>屬性,選擇你最喜愛的旋轉器作為加載動畫:
<infinite-loading spinner="{{ spinner name }}"></infinite-loading>
點擊這里可以查看幾個可用的旋轉器。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。