1.使用express框架开发商品列表查询接口
- 安装mongoose,对mongodb的封装,提供了增删改查的API,方便对数据库进行操作。
- 创建model 实体,更mongodb数据库进行关联。
- 创建路由 通过路由调model实体,通过model 实体的API来查询数据库
-给予mongoose实现商品列表的查询功能。
实现步骤
-安装mongoose
-
1、在server下建一个models文件夹,在models下建goods.js,代码如下:
var mongoose=require('mongoose');
var Schema=mongoose.Schema;//Schema是一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力。schema可以理解为mongoose对表结构的定义
//schema不具备操作数据库的能力
var productSchema= new Schema({ //创建实体,字段和数据库的goods字段一致,如果不一致就插不进来数据,这就防止了数据库的乱插入。
"productId":String,
"productName":String,
"salePrice":Number,
"productImage":String
});
module.exports=mongoose.model('good',productSchema);//创建并导出实体,名为good,和数据库的goods匹配,实体方法是productSchema
//Model是由Schema编译而成的假想(fancy)构造器,具有抽象属性和行为。Model的每一个实例(instance)就是一个document。document可以保存到数据库和对数据库进行操作。
mongoose简要API:https://www.cnblogs.com/winyh/p/6682039.html
-
2、在routes下创建文件goods.js
var express=require('express');
var router=express.Router();
var mongoose=require('mongoose');
var Goods= require('../models/goods');
//var Users= require('../models/users');
//链接数据库
mongoose.connect('mongodb://127.0.0.1:27017/mall');
//监听数据库是否链接成功
mongoose.connection.on('connected',()=>{
console.log("mongodb connected success")
});
mongoose.connection.on('error',()=>{
console.log("mongodb connected fail")
});
mongoose.connection.on('disconnected',()=>{
console.log("mongodb connected disconnected")
});
router.get('/',(req,res,next)=>{
//获取前端传来的参数req.param
let sort=+req.param("sort");
let page=+req.param("page");
let pageSize=+req.param("pageSize");
let skip=(page-1)*pageSize
let priceLevel=req.param("priceLevel");
let startPrice;
let endPrice;
//查询数据库
let params;//查询字段
//根据价格选择来设置合适的查询字段
if(priceLevel !== "all"){
switch(priceLevel){
case "0":startPrice=0;endPrice=100;break;
case "1":startPrice=100;endPrice=500;break;
case "2":startPrice=500;endPrice=1000;break;
case "3":startPrice=1000;endPrice=2000;break;
}
params={
salePrice:{
$gt:startPrice,
$lte:endPrice
}
}
}else{
params={};
}
let goodsModel=Goods.find(params);
goodsModel.sort({"salePrice":sort}).skip(skip).limit(pageSize);//sort排序,skip条股票多少条数据,limit限制多少条数据
goodsModel.exec((err,doc)=>{
if(err){
res.json({//返回json数据
status:'1',
msg:err.message
})
}else{
res.json({
status:'0',
msg:'',
result:{
count:doc.length,
list:doc//把查询到的数据返回给前端
}
})
}
})
})
module.exports=router;
-
3、分页功能实现
思路:前端通过axios传过去参数params,后端接受并解析出来对应的页码page,页面数据条数pageSize,和排序参数sort,然后后端根据这些参数进行排序过滤和分页。
先是进行排序,然后用skip过滤掉前面几页的数据((page-1)*pageSize),最后用limit限制此页的数据。
//前端的views/goodsList.js
getGoodList(flag){
axios.get("/goods",{
params:{
page:this.page,
pageSize:this.pageSize,
sort:this.sortFlag?1:-1,
priceLevel:this.priceChecked
}
}).then((result)=>{
var res=result.data;
this.goodsList=res.result.list;
})
},
//后端的routes/goods.js
router.get('/',(req,res,next)=>{
//获取前端传来的参数req.param
let sort=+req.param("sort");
let page=+req.param("page");
let pageSize=+req.param("pageSize");
let skip=(page-1)*pageSize
goodsModel.sort({"salePrice":sort}).skip(skip).limit(pageSize);//sort排序,skip条股票多少条数据,limit限制多少条数据
goodsModel.exec({},(err,doc)=>{
if(err){
res.json({//返回json数据
status:'1',
msg:err.message
})
}else{
res.json({
status:'0',
msg:'',
result:{
count:doc.length,
list:doc//把查询到的数据返回给前端
}
})
}
})
})
module.exports=router;
4、滚动分页加载
采用插件vue-infinite-scroll
使用方法:https://segmentfault.com/a/1190000011693433
//引入
import infiniteScroll from 'vue-infinite-scroll'
directives: {infiniteScroll},
<div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
加载中...
</div>
loadMore中添加滚动10px后的处理方法。busy为true代表禁用无限滚动。
loadMore(){//加载更多数据
this.busy=true;
this.page++;
this.getGoodList(true);//参数flag为true代表之前有数据,后边的分页数据需要拼接起来
}
此时补充getGoodList函数
getGoodList(flag){
axios.get("/goods",{
params:{
page:this.page,
pageSize:this.pageSize,
sort:this.sortFlag?1:-1,
priceLevel:this.priceChecked
}
}).then((result)=>{
var res=result.data;
if(flag){//如果之前有加载的数据再请求时就拼接起来
this.goodsList=this.goodsList.concat(res.result.list);
}else{
this.goodsList=res.result.list;
}
//判断当数据小于一页的数量时就设为true,禁用无限滚动,若没小于请求完数据后就可以启用滚动了
if(res.result.count<this.pageSize){
this.busy=true;
}else{
this.busy=false;
}
}).catch((err)=>{
console.log(err);
this.busy=true;//如果抱错了就禁用无限滚动
})
},
-
5、价格过滤
通过priceChecked将priceLevel传到后端,priceLevel包含all,1,2,3,4
后端进行筛选处理
//查询数据库
let params;//查询字段
//根据价格选择来设置合适的查询字段
if(priceLevel !== "all"){
switch(priceLevel){
case "0":startPrice=0;endPrice=100;break;
case "1":startPrice=100;endPrice=500;break;
case "2":startPrice=500;endPrice=1000;break;
case "3":startPrice=1000;endPrice=2000;break;
}
params={
salePrice:{
$gt:startPrice,
$lte:endPrice
}
}
}else{
params={};
}
let goodsModel=Goods.find(params);
goodsModel.sort({"salePrice":sort}).skip(skip).limit(pageSize);//sort排序,skip条股票多少条数据,limit限制多少条数据
-
6、加入购物车功能实现
首先在前端GoodList页面实现点击‘加入购物车按钮’将商品信息加入到数据库users表的cartList数组中。
前端点击函数:
通过axios发送post请求,请求路径是/goods/addCart,传的参数是productId
addCart(productId){//加入购物车
axios.post("/goods/addCart",{
productId:productId
}).then((res)=>{
if(res.data.status==0){
alert("加入成功");
}else{
alert("error:"+res.msg)
}
})
}
},
后端服务器处理:
首先找到users表中用户id的数据表doc1,对doc1的cartList进行遍历循环,如果某一个商品id和当前加入购物车的商品id(前端传进来的参数,通过req.body解析)一样的话,就说明这个购物车已经存在了,exist设为true,只需要把cartList中的这个商品的productNum++即可,然后保存doc1。如果遍历完了exist并没有设为true(初始值为false),说明这个商品之前并没有加进购物车,所以接下来先找到Goods中的这个商品doc2,找到之后给这个商品添加两个字段checked和productNum用以记录是否被选中和商品数量,然后将doc2push进doc1的cartList数组中,最后保存。(注意设置checked和productNum时在model实体good中如果没有这两个字段的话是插入不进去的,所以需要在models下的good.js中补充这两个字段)
router.post('/addCart', (req, res, next) => {
let exist = false;
let userId = "100000077";
let productId = req.body.productId;
let params = { userId: userId };
let usersModel = Users.findOne(params);
usersModel.exec((err1, doc1) => {
doc1.cartList.forEach((item) => {
if (item.productId == productId) {
exist = true;
item.productNum++;
doc1.save((err, doc) => {
if (err) {
res.json({
status: '1',
msg: err.message
})
} else {
res.json({
status: '0',
result: 'sucess'
})
}
})
}
})
if (!exist) {
let good = Goods.findOne({ productId: productId }, (err2, doc2) => {
if (err2) {
res.json({
status: '1',
msg: err2.message
})
} else {
console.log(doc2)
doc2.checked = 1;
doc2.productNum = 1;
doc1.cartList.push(doc2);
doc1.save((err, doc) => {
if (err) {
res.json({
status: '1',
msg: err.message
})
} else {
res.json({
status: '0',
result: 'sucess'
})
}
})
}
})
}
})
})
网友评论