在vue中實現下拉載入資料,瀑布流
說明
節約流量
提高使用者體驗
不至於每次把所有資料載入出來,出現使用者等待時間較長
實現方式
需求:
當使用者開啟首頁的時候顯示8條資料,當使用者滾動到螢幕可視區邊緣的時候,然後觸發一個函式,請求一個api載入新的資料,並且填充到之前的資料下面。
實現:
vue-infinite-scroll
vue外掛:vue-infinite-scroll
github地址
安裝
npm i vue-infinite-scroll -D
在main.js入口檔案裡面引入
使用CommonJS方式
// 註冊全域性
var infiniteScroll = require(`vue-infinite-scroll`);
Vue.use(infiniteScroll)
//單獨的元件裡面使用
var infiniteScroll = require(`vue-infinite-scroll`);
new Vue({
directives: {infiniteScroll}
})
使用 ES2015的方式
// 註冊全域性
import infiniteScroll from `vue-infinite-scroll`
Vue.use(infiniteScroll)
//單獨的元件裡面使用
import infiniteScroll from `vue-infinite-scroll`
new Vue({
directives: {infiniteScroll}
})
使用方式
Use v-infinite-scroll to enable the infinite scroll, and use infinite-scroll-* attributes to define its options.
使用v-infinite-scroll啟用無限滾動,並使用無限滾動- *屬性來定義它的選項。
The method appointed as the value of v-infinite-scroll will be executed when the bottom of the element reaches the bottom of the viewport.
當元素底部到達viewport底部時,將觸發v-infinite-scroll值的方法。
<div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
...
</div>
var count = 0;
new Vue({
el: `#app`,
data: {
data: [],
busy: false
},
methods: {
loadMore: function() {
this.busy = true;
setTimeout(() => {
for (var i = 0, j = 10; i < j; i++) {
this.data.push({ name: count++ });
}
this.busy = false;
}, 1000);
}
}
});
選項
選項 | 描述 |
---|---|
infinite-scroll-disabled | 如果該屬性的值為true,則將禁用無限滾動。 |
infinite-scroll-distance | 數字(預設值= 0)——在執行v -infinite- scroll方法之前,元素底部和viewport底部之間的最小距離。 |
infinite-scroll-immediate-check | 布林值(預設值= true)表示該指令應該在繫結後立即檢查。如果可能,內容不夠高,不足以填滿可滾動的容器。 |
infinite-scroll-listen-for-event | 當事件在Vue例項中發出時,無限滾動將再次檢查。 |
infinite-scroll-throttle-delay | 下次檢查和這次檢查之間的間隔(預設值= 200) |
後端實現:
需求分析:
接收引數:
每頁有多少條 prePage
第幾頁(當前頁) page
當我們第一次載入資料的時候載入8條
區分第一次和不是第一次載入
程式碼實現
在dom裡面
<div class="accessory-list-wrap">
<div class="accessory-list col-4">
<ul>
<li v-for="(item,index) in goods" :key="index">
<div class="pic">
<a href="#"><img v-lazy="`/static/img/` + item.productImage" alt=""></a>
</div>
<div class="main">
<div class="name">{{item.productName}}</div>
<div class="price">{{item.salePrice}}</div>
<div class="btn-area">
<a href="javascript:;" class="btn btn--m">加入購物車</a>
</div>
</div>
</li>
<div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
...
</div>
</ul>
</div>
</div>
vue 元件裡面:
data(){
return{
busy: true,
page:1,
pageSize:8,
}
},methods:{
getGoodsList(flag){
let sort = this.sortFlag ? 1 : -1;
let param = {
sort:sort,
priceLevel:this.priceChecked,
page:this.page,
pageSize:this.pageSize
}
axios.get(`/goods/list`,{params:param}).then(res=>{
if(flag){
// 多次載入資料
this.goods = this.goods.concat(res.data.result);
if(res.data.result.length == 0){
this.busy = true;
}else{
this.busy = false;
}
}else{
// 第一次載入資料
this.goods = res.data.result;
// 當第一次載入資料完之後,把這個滾動到底部的函式觸發開啟
this.busy = false;
}
})
},
loadMore: function() {
this.busy = true;
// 多次載入資料
setTimeout(() => {
this.page ++;
this.getGoodsList(true);
}, 1000);
}
}
let currentPage = parseInt(req.param(`page`)) > 0 ? parseInt(req.param(`page`)) : 1;
let pageSize = parseInt(req.param(`pageSize`)) > 0 ? parseInt(req.param(`pageSize`)) : 8;
// 要跳過多少條
let skip = (currentPage - 1) * pageSize;
let goodsModel = Goods.find(param);
goodsModel.sort({ `salePrice`: sort }).skip(skip).limit(pageSize);
goodsModel.exec({}, function(err, doc) {
if (err) {
res.json({ status: "1", msg: err.message })
} else {
res.json({ status: `0`, msg: ``, result: doc })
}
})