热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Vuenode.js商城购物车模块

一、渲染购物车列表页面新建srcviewsCart.vue获取cartList购物车列表数据就可以在页面中渲染出该用户的购物车列表数据data(){return{cartList

 

一、渲染购物车列表页面

新建src/views/Cart.vue
获取cartList购物车列表数据就可以在页面中渲染出该用户的购物车列表数据


  1. data(){
  2.   return {
  3.      cartList:[] // 购物车商品列表
  4.   }
  5. },
  6. mounted:function(){
  7.   this.init();
  8. },
  9. methods:{
  10.   init(){ // 初始化商品数据
  11.     axios.get('/users/cartList').then((response)=>{
  12.       let res = response.data;
  13.       this.cartList = res.result;
  14.     })
  15.   }
  16. }

购物车接口:server/routes/users.js


  1. // 查询当前用户的购物车数据
  2. router.get('/cartList',function(req,res,next){
  3.     var userId = req.COOKIEs.userId;
  4.     User.findOne({userId:userId},function(err,doc){
  5.         if(err){
  6.             res.json({
  7.                 status:'1',
  8.                 msg:err.message,
  9.                 result:''
  10.             });
  11.         }else{
  12.             if(doc){
  13.                 res.json({
  14.                     status:'0',
  15.                     msg:'',
  16.                     result:doc.cartList
  17.                 })
  18.             }
  19.         }
  20.     })
  21. })

建立路由src/router/index.js


  1. import Cart from '@/views/Cart' // 购物车列表
  2. export default new Router({
  3.   routes: [
  4.     {
  5.       path: '/cart', // 购物车列表路由
  6.       name: 'Cart',
  7.       component: Cart
  8.     }
  9.   ]
  10. })

二、购物车商品删除功能

购物车删除接口:server/routes/users.js


  1. // 购物车删除功能
  2. router.post('/cartDel',function(req,res,next){
  3.     var userId = req.COOKIEs.userId,productId = req.body.productId;
  4.     User.update({
  5.         userId:userId
  6.     },{
  7.         $pull:{
  8.             'cartList':{
  9.                 'productId':productId
  10.             }
  11.         }
  12.     },function(err,doc){
  13.         if(err){
  14.             res.json({
  15.                 status:'1',
  16.                 msg:err.message,
  17.                 result:''
  18.             });
  19.         }else{
  20.             res.json({
  21.                 status:'0',
  22.                 msg:'',
  23.                 result:'suc'
  24.             });
  25.         }
  26.     })
  27. });

src/views/Cart.vue


  1. 点击删除图标模态框出现(导入模态Modal.vue子组件)
  2.     class="icon icon-del">
  3.         #icon-del">
  4.     
  5. modalConfirm" @close="closeModal">
  6.     

    message">你确认要删除此条数据吗?

  7.     
    btnGroup">
  8.     
  • import Modal from '@/components/Modal.vue' // 模态框
  • export default {
  •     data(){
  •         return {
  •           productId:'',
  •           modalConfirm:false // 模态框是否显示
  •         }
  •     },
  •     components:{
  •       Modal
  •     },
  •     methods:{
  •       delCartConfirm(productId){ // 点击删除图标
  •         this.productId = productId;
  •         this.modalConfirm = true; // 模态框显示
  •       },
  •       closeModal(){ // 关闭模态框
  •         this.modalConfirm = false;
  •       },
  •       delCart(){ // 确认删除此商品
  •         axios.post('/users/cartDel',{
  •           productId:this.productId
  •         }).then((response) => {
  •           let res = response.data;
  •           if(res.status = '0'){
  •             this.modalConfirm = false; // 关闭模态框
  •             this.init(); // 重新初始化购物车数据
  •           }
  •         })
  •       }
  •     }
  • }
  • **** 在这里发现一个bug,在商品列表页点击"加入购物车",购物车页面新添加的商品数量和总价格是未定义。mongoose添加属性问题

    这是后端接口处理的问题,在server/routes/goods.js的加入到购物车接口中,是从mongodb的数据库dumallgoods表根据商品id获取对应数据,再对此商品数据添加productNumchecked属性,之后再插入到users表的购物车列表中的。

    属性没有添加成功,在Goods模型中添加属性,要去models/goods.jsSchema添加这两个属性。


    1. server/models/goods.js
    2. // 定义一个Schema
    3. var produtSchema = new Schema({
    4.    'productId':String,
    5.    'productName':String,
    6.    'salePrice':Number,
    7.    'productImage':String,
    8.     // 添加的属性
    9.     "checked":String,
    10.     "productNum":Number
    11. })
    12. module.exports = mongoose.model('good',produtSchema);

     

    重新启动express(node server/bin/www)

    三、购物车商品修改功能

    商品加减和商品勾选

    server/routes/users.js


    1. //修改商品数量接口
    2. router.post("/cartEdit",function(req,res,next){
    3.     var userId = req.COOKIEs.userId,
    4.         productId = req.body.productId,
    5.         productNum = req.body.productNum,
    6.         checked = req.body.checked;
    7.     User.update({ // 查询条件
    8.         "userId":userId,
    9.         "cartList.productId":productId
    10.     },{ // 修改的数据
    11.         "cartList.$.productNum":productNum,
    12.         "cartList.$.checked":checked
    13.     },function(err,doc){
    14.         if(err){
    15.           res.json({
    16.             status:'1',
    17.             msg:err.message,
    18.             result:''
    19.           });
    20.         }else{
    21.           res.json({
    22.             status:'0',
    23.             msg:'',
    24.             result:'suc'
    25.           });
    26.         }
    27.     });
    28. })

    src/views/Cart.vue


    1. javascipt:;" class="checkbox-btn item-check-btn" v-bind:class="{'check':item.checked=='1'}" @click="editCart('checked',item)">
    2.     class="icon icon-ok">
    3.         #icon-ok">
    4.     
    5. class="input-sub" @click="editCart('minu',item)">-
    6. class="input-add" @click="editCart('add',item)">
    7. methods:{
    8.     editCart(flag,item){
    9.         if(flag == 'add'){ // 添加商品数量
    10.           item.productNum ;
    11.         }else if(flag = 'minu'){ // 减少商品数量
    12.           if(item.productNum <&#61; 1){
    13.             return;
    14.           }
    15.           item.productNum--;
    16.         }else{ // 商品控制选中
    17.           item.checked &#61; (item.checked&#61;&#61;&#39;1&#39;) ? &#39;0&#39; : &#39;1&#39;;
    18.         }
    19.         axios.post(&#39;/users/cartEdit&#39;,{
    20.           productId:item.productId,
    21.           productNum:item.productNum,
    22.           checked:item.checked
    23.         }).then((response)&#61;>{
    24.           let res &#61; response.data;
    25.         })
    26.       }
    27. }

    购物车全选和商品实时计算功能


    server/routes/users.js


    1. //全选和取消全选
    2. router.post(&#39;/editCheckAll&#39;,function(req,res,next){
    3.     var userId &#61; req.COOKIEs.userId,
    4.       checkAll &#61; req.body.checkAll?&#39;1&#39;:&#39;0&#39;;
    5.     User.findOne({userId:userId},function(err,user){
    6.         if(err){
    7.           res.json({
    8.             status:&#39;1&#39;,
    9.             msg:err.message,
    10.             result:&#39;&#39;
    11.           });
    12.         }else{
    13.           if(user){
    14.             user.cartList.forEach((item)&#61;>{
    15.               item.checked &#61; checkAll;
    16.             })
    17.             user.save(function (err1,doc) {
    18.                 if(err1){
    19.                   res.json({
    20.                     status:&#39;1&#39;,
    21.                     msg:err1,message,
    22.                     result:&#39;&#39;
    23.                   });
    24.                 }else{
    25.                   res.json({
    26.                     status:&#39;0&#39;,
    27.                     msg:&#39;&#39;,
    28.                     result:&#39;suc&#39;
    29.                   });
    30.                 }
    31.             })
    32.           }
    33.         }
    34.     })
    35. })

    src/views/Cart.vue


    1. javascipt:;" &#64;click&#61;"toggleCheckAll">
    2.     class&#61;"checkbox-btn item-check-btn" v-bind:class&#61;"{&#39;check&#39;:checkAllFlag}">
    3.         class&#61;"icon icon-ok">#icon-ok"/>
    4.     
    5.     Select all
    6. export default {
    7.     data(){
    8.         return {
    9.           checkAllFlag:false // 控制全选
    10.         }
    11.     },
    12.     methods:{
    13.       toggleCheckAll(){ // 全选和取消全选
    14.         this.checkAllFlag &#61; !this.checkAllFlag; // 取反
    15.         this.cartList.forEach((item)&#61;>{
    16.           item.checked &#61; this.checkAllFlag;
    17.         })
    18.         axios.post(&#39;/users/editCheckAll&#39;,{
    19.           checkAll:this.checkAllFlag
    20.         }).then((response)&#61;>{
    21.           let res &#61; response.data;
    22.           if(res.status&#61;&#61;&#39;0&#39;){
    23.             console.log("update suc");
    24.           }
    25.         })
    26.       }
    27.     }
    28. }

     

    这里出现一个问题&#xff0c;在点击select All全选之后&#xff0c;显示正常&#xff0c;但是刷新页面之后全选的图标没有显示全选&#xff0c;因为全选的信息没有存储到数据库保存&#xff0c;所以刷新之后就没有了。

    【解决的办法】

    用到了实时计算的computed功能&#xff0c;实时计算的是属性&#xff0c;只不过是函数的写法&#xff0c;data里面就不用在声明了。

    src/views/Cart.vue


    1. export default {
    2.     data(){
    3.         return {
    4.           // checkAllFlag:false // 控制全选
    5.         }
    6.     },
    7.     computed:{ // 实时计算的是属性&#xff0c;只不过是函数的写法&#xff0c;data里面就不用在声明了
    8.       checkAllFlag(){ // 是否全选属性
    9.         return this.checkedCount &#61;&#61; this.cartList.length; // 勾选的商品种数&#61;购物车商品列表的商品种数时&#xff0c;返回true代表全选。
    10.       },
    11.       checkedCount(){ // 获取已勾选的商品种数(几种商品已勾选)
    12.         var i &#61; 0;
    13.         this.cartList.forEach((item)&#61;>{
    14.           if(item.checked&#61;&#61;&#39;1&#39;)i ;
    15.         });
    16.         return i;
    17.       }
    18.     },
    19.     methods:{
    20.       toggleCheckAll(){ // 全选和取消全选
    21.         // this.checkAllFlag &#61; !this.checkAllFlag;
    22.         // 不能使用这种写法了&#xff0c;checkAllFlag是实时计算的属性&#xff0c;如果true取反变成false之后&#xff0c;还没来得及执行下面的所有商品取消勾选&#xff0c;就实时计算了检测到勾选的商品种数&#61;购物车商品列表的商品种数,就又变成全选了。
    23.         var flag &#61; !this.checkAllFlag; // 声明变量取代
    24.         this.cartList.forEach((item)&#61;>{
    25.           item.checked &#61; flag ?&#39;1&#39;:&#39;0&#39;;
    26.         })
    27.         axios.post(&#39;/users/editCheckAll&#39;,{
    28.           checkAll:flag
    29.         }).then((response)&#61;>{
    30.           let res &#61; response.data;
    31.           if(res.status&#61;&#61;&#39;0&#39;){
    32.             console.log("update suc");
    33.           }
    34.         })
    35.       }
    36.     }
    37. }

     

    页面一刷新就实时计算了


    这里也要用到computed计算属性


    1. class&#61;"item-total">
    2.   Item total: class&#61;"total-price">{{totalPrice}}
  • computed:{
  •     totalPrice(){ // 总价格属性
  •         var money &#61; 0;
  •         this.cartList.forEach((item)&#61;>{
  •             if(item.checked&#61;&#61;&#39;1&#39;){
  •                 money &#61; parseFloat(item.salePrice)*parseInt(item.productNum);
  •             }
  •         });
  •         return money;
  •     }
  • }
  •  

    接下来要对价格进行格式化&#xff0c;vuex官网github有一个对购物车将格式化的函数https://github.com/vuejs/vuex/blob/dev/examples/shopping-cart/currency.js 可以拿过来对价格格式化&#xff0c;在src/util/currency.js

    格式化要用到过滤器&#xff1a;可以在src/views/Cart.vue导入使用局部过滤器&#xff0c;也可以在main.js使用全局过滤器


    1. class&#61;"total-price">{{totalPrice | currency(&#39;$&#39;)}}
    2. // 局部过滤器
    3. import {currency} from &#39;&#64;/util/currency.js&#39;
    4. filters:{
    5.   currency:currency // currency.js传过来的本就是函数
    6. },
    7. // 全局过滤器
    8. import {currency} from &#39;./util/currency&#39;
    9. Vue.filter("currency",currency);

     



    更多专业前端知识&#xff0c;请上
    【猿2048】www.mk2048.com
    推荐阅读
    author-avatar
    1031372720_eba8d5
    这个家伙很懒,什么也没留下!
    Tags | 热门标签
    RankList | 热门文章
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有