Vue+nodejs商城项目前后端数据传递,排序与分页功能实现
前后端数据传递
后端数据库采用mongodb,mongodb是非关系型数据库,存储集合。
1、首先下载moongose插件可以很方便的从mongodb中获取数据
在node搭建的服务端Server新建文件\model\goods
var mongoose = require('mongoose');
//moongose可以简捷的从mongoDB中获取数据
//moongose有一个模式Schema,用于定义从mongodb中查询的每一个条目
var Schema = mongoose.Schema;
//数据对象的模板
var productSchema = new Schema({
"productId":String,
"productName":String,
"salePrice":Number,
"productImage":String
});
//输出数据对象
module.exports = mongoose.model('Goods',productSchema);
使用moogose中的模式Schema定义查询模型并输出。
2、nodeJS端查询数据并返回结果\routes\goods
先导入相关模块,用到了express框架和moogose,model
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Goods = require('../models/goods');
连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/数据库名称');
mongoose.connection.on("connected",function () {
console.log("MongoDB connected success");
});
mongoose.connection.on("error",function () {
console.log("MongoDB connected fail");
});
mongoose.connection.on("disconnected",function () {
console.log("MongoDB connected disconnected");
});
查询数据
使用Express.Router(),对前端的get请求进行响应,并把结果放在result.list中,与status,msg一起以json形式返回给客户端
router.get("/",function (req,res,next) {
//用Goods模板调用moogoseAPI进行数据库查询
Goods.find({},function (err,doc) {
if(err){
res.json({
status:'1',
msg:err.message
});
}else{
res.json({
status:'0',
msg:'',
result:{
count:doc.length,
//查询结果
list:doc
}
})
}
})
});
3、客户端接收数据
跨域代理
nodejs执行的数据在localhost:3000,vue运行在8080,需要在config/index.js的dev下添加转发代理
proxyTable: {
'/goods':{
target:'http://localhost:3000'
}
每当vue利用axios访问/goods时时,就将地址转到3000
4、vue进行数据请求并渲染到界面
在mounted挂载一个getGoodsList()的方法,载入后调用这个方法。通过axios的/goods发送请求,刚刚编辑跨域代理,通过/goods可以请求到nodejs。data中存储返回的实际内容,status状态码为0时,表示成功,数据在result.llist中,对list进行遍历就可以将数据渲染到界面
mounted:function (){
this.getGoodsList();
},
methods:{
getGoodsList(){
axios.get("/goods").then(response =>{
let res=response.data;
if(res.status==0){
this.goodsList=res.result.list;
}else{
console.log("从服务器请求数据失败!");
}
})
},
v-for进行循环,图片利用插件用到了懒加载v-lazy
<ul>
<li v-for = "(item,index) in goodsList">
<div class="pic">
<a href="#"><img v-lazy="'/static/'+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>
</ul>
根据商品价格排序+分页
商品按价格排序主要是利用nodejs的mongoose中的sort函数对数据库查询结果按price关键字排序,之后返回给前端。在前端发送排序请求:
router.get("/",function (req,res,next) {
//接受从前端传来的数据
let page = parseInt(req.param("page"));//前端参数页码
let pageSize = parseInt(req.param("pageSize"));//每一页条数
let sort = req.param("sort");//1正序,-1反序
let skip = (page-1)*pageSize;//计算要跳过多少条数据
//排序
let params = {};
let goodsModel = Goods.find(params).skip(skip).limit(pageSize);
goodsModel.sort({'salePrice':sort});
//用Goods模板调用moogoseAPI进行数据库查询
goodsModel.exec(function (err,doc) {
if(err){
res.json({
status:'1',
msg:err.message
});
}else{
res.json({
status:'0',
msg:'',
result:{
count:doc.length,
//查询结果
list:doc
}
})
}
})
});
前端排序定义了sortFlag:true时正序,false反序
sortGoods(){
this.sortFlag = !this.sortFlag;//取反
//排序之后将页码置为,再去请求结果
this.page=1;
this.getGoodsList();
}
前端使用了v-infinite-scroll插件来实现分页,这个插件当滑倒定义的窗口底端时触发加载下一页。
<div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="30">
加载中...
</div>
v-infinite-scroll="loadMore"是一个触发时加载的方法
infinite-scroll-disabled="busy"这个属性控制是否启用加载,busy为true,禁用,false时启用。
infinite-scroll-distance="30"定义窗口高度。
loadMore(){
this.busy = true;
setTimeout(() => {
this.page++;
this.getGoodsList(true);
}, 500);
页面初始禁用滚动加载,busy为true,加载时页数增加,重新调用商品列表,500毫秒为加载时间,避免加载过于灵敏。
getGoodsList(flag)添加一个参数用来区分是第一次加载、排序还是分页,flag为true,表明是分页,数据需要累加,第一次加载和排序不需要累加数据
getGoodsList(flag){
var param={
page :this.page,
pageSize: this.pageSize,
sort:this.sortFlag?1:-1
}
//axios的get请求/goods,由于上面做了跨域代理,可以向nodeJS服务端发送请求
axios.get("/goods",{
//axios要通过params写入参数
params:param
}).then((response)=>{
let res = response.data;
if(res.status==="0"){
if(flag){
//flag为true时,表明是分页,数据需要累加
this.goodsList = this.goodsList.concat(res.result.list);
if(res.result.count===0){
//数据为0条时,禁用滚动
this.busy = true;
}else{
this.busy = false;
}
}else{
//第一次进入
this.goodsList = res.result.list;
this.busy = false;
}
}else{
this.goodsList=[];
}
});
},
上一篇: 富文本编辑器的使用