在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 })
}
})
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。