简介
设想一下,如果商品条目数量很多,假设有100条,如果我们一次性拉下来,是很影响性能的。所以我们需要为商品列表添加分页功能。本篇主要实现以下目的:
- 后端分页功能逻辑实现
- 前端分页功能逻辑实现
1. 后端分页功能逻辑实现
这里我们有如下约定;
- 后端需要接收参数page和pageSize。
- page表示请求第几页数据。
- pageSize表示每页返回的数目。
- 按pageSize分页并返回指定页数的数据。
修改routes/goods.js文件如下:
/* GET goods */
router.get('/', function (req, res, next) {
// 只有接口请求带参数sort=priceDown才会按价格降序
let sort = req.query['sort'] === 'priceDown'?-1:1;
let startPrice = req.query['startPrice'];
let endPrice = req.query['endPrice'];
let page = parseInt(req.query['page']);
let pageSize = parseInt(req.query['pageSize']);
// 价格筛选处理逻辑
startPrice = startPrice? parseInt(startPrice):0;
endPrice = endPrice?parseInt(endPrice):undefined;
console.log(startPrice, endPrice);
let params = {};
if (endPrice) {
params = {salePrice: {$gt: startPrice, $lte: endPrice}};
} else {
params = {salePrice: {$gt: startPrice}};
}
// 分页处理逻辑
if (!(page > 0 && pageSize > 0)) {
res.json({
code: '801',
msg: '请求参数有误'
});
return;
}
let skip = (page - 1)*pageSize;
// 查询起始价(不包含)到结尾价(包含)区间的商品,并分页返回
let query = Good.find(params).skip(skip).limit(pageSize);
query.sort({salePrice: sort});
query.exec((err, doc) => {
if (err) {
res.json({
code: '900',
msg: err.message || '服务器错误'
})
} else {
res.json({
code: '000',
msg: '',
result: {
count: doc.length,
list: doc
}
})
}
});
});
2. 前端分页功能逻辑实现
这里我们不再详述与后端分离开发的逻辑,直接使用已经开发好的后端接口来看效果。
step1 在前端写死分页参数请求数据并展示
此处由于后端返回的数据结构有了变化,为了看到效果,我们首先要更改一下前端数据处理逻辑。
export default {
data () {
return {
prdList: [], // 产品列表
// 价格过滤列表
priceFilterList: [
{
startPrice: 0,
endPrice: 100
},
{
startPrice: 100,
endPrice: 500
},
{
startPrice: 500,
endPrice: 2000
},
{
startPrice: 2000
}
],
priceChecked: 'all', // 选中的价格过滤列表项
filterPrice: null, // 选中的价格过滤列表对象
isShowFilterBy: false, // 是否展示过滤列表弹窗
isShowOverLay: false, // 是否展示遮罩层
page: 1,
pageSize: 8,
sortChecked: 'default',
isPriceUp: true
}
},
computed: {
isPriceArrowUp () {
return !this.isPriceUp
}
},
components: {
PageHeader,
PageBread,
PageFooter
},
created () {
this.getPrdList()
},
methods: {
// 请求接口获取产品列表数据
getPrdList () {
queryPrdObj = Object.assign({}, this.filterPrice, {page: this.page, pageSize: this.pageSize, sort: this.sortChecked})
axios.get('/api/goods', {params: queryPrdObj}).then((res) => {
console.log('res', res)
let data = (res && res.data) || {}
if (data.code === '000') {
let result = data.result || {}
this.prdList = result.list || []
console.log('prdList', this.prdList)
} else {
alert(`err:${data.msg || '系统错误'}`)
}
})
},
// 选取价格过滤列表项
checkPriceFilter (index) {
this.priceChecked = index
this.filterPrice = index === 'all' ? null : this.priceFilterList[index]
this.getPrdList()
this.closeFilterBy()
},
// 展示过滤列表弹窗
showFilterBy () {
this.isShowFilterBy = true
this.isShowOverLay = true
},
// 关闭过滤列表弹窗
closeFilterBy () {
this.isShowFilterBy = false
this.isShowOverLay = false
},
checkSort (val) {
this.sortChecked = val
if (val === 'priceUp' || val === 'priceDown') {
this.isPriceUp = !this.isPriceUp
} else {
this.isPriceUp = true
}
this.getPrdList()
}
}
}
step2 使用vue-infinite-loading进行上拉加载
关于vue-infinite-loading使用方法见官网。
安装;
npm install vue-infinite-loading --save
修改GoodsList.vue文件如下:
Goods
-
No more ...
总结
到此,商品列表页的查询展示逻辑基本上完成了。
我们提交代码:
- six-tao
git status
git diff
git commit -am 'add vue-infinite-loading'
git push
- six-tao-server
git status
git diff
git commit -am 'paging logic done'
git push