欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Vue+nodejs商城项目前后端数据传递,排序与分页功能实现

程序员文章站 2022-03-05 07:52:47
...

前后端数据传递

后端数据库采用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=[];
          }
        });
      },
相关标签: 前端框架