当前位置:   article > 正文

用vue实现一个淘宝购物车,给和我一样苦苦挣扎的前端小白(更新)

淘宝购物车vue前端和javaweb代码

最近后端的同事要我写一个购物车,一开始我用jQuery写,但写着写着发现逻辑太混乱了,写不下去。最后花了五分钟找了个demo丢给了他。后来我不甘心,毕竟水平菜还不求上进就完蛋了。所以我想着用vue来实现一个。

  1. 本来想看看别人的代码,但搜索了下github发现,能找到的购物车都是两级分类的。而京东、淘宝之流都是三级分类的:
  2. 1. 全选
  3. 2. 店铺全选
  4. 3. 商品选中

这样的貌似才有实用价值

html部分,不过多赘述

  1. <div id="cart">
  2. <section class="cartMain">
  3. <div class="cartMain_hd">
  4. <ul class="order_lists cartTop">
  5. <li class="list_chk">
  6. <!--所有商品全选-->
  7. <input type="checkbox" id="all" class="whole_check">
  8. <label for="all" :class="fetchData.status?'mark':''" @click="cartchoose()"></label>
  9. 全选
  10. </li>
  11. <li class="list_con">商品信息</li>
  12. <li class="list_info">商品参数</li>
  13. <li class="list_price">单价</li>
  14. <li class="list_amount">数量</li>
  15. <li class="list_sum">金额</li>
  16. <li class="list_op">操作</li>
  17. </ul>
  18. </div>
  19. <div class="cartBox" v-for="item in fetchData.list" key="index">
  20. <div class="shop_info">
  21. <div class="all_check">
  22. <input type="checkbox" id="shop_a" class="shopChoice">
  23. <label for="shop_a" class="shop" :class="item.check?'mark':''" @click="shopchoose(item)"></label>
  24. </div>
  25. <div class="shop_name">
  26. 店铺:<a href="javascript:;">{{item.shop_name}}</a>
  27. </div>
  28. </div>
  29. <div class="order_content">
  30. <ul class="order_lists" v-for="pro in item.products">
  31. <li class="list_chk">
  32. <input type="checkbox" id="checkbox_2" class="son_check">
  33. <label for="checkbox_2" :class="pro.checked?'mark':''" @click="choose(item,pro)"></label>
  34. </li>
  35. <li class="list_con">
  36. <div class="list_img"><a href="javascript:;"><img :src="pro.img" alt=""></a></div>
  37. <div class="list_text"><a href="javascript:;">{{pro.text}}</a>
  38. <span class="list_custom">定制</span>
  39. </div>
  40. </li>
  41. <li class="list_info">
  42. <p>规格:默认</p>
  43. <p>尺寸:16*16*3(cm)</p>
  44. </li>
  45. <li class="list_price">
  46. <p class="price">¥{{pro.price}}</p>
  47. <div class="charge">
  48. <p>更多促销</p>
  49. <div class="chargebox">
  50. 测试
  51. </div>
  52. </div>
  53. </li>
  54. <li class="list_amount">
  55. <div class="amount_box">
  56. <a href="javascript:;" class="reduce reSty" @click="reduce(pro)">-</a>
  57. <input type="text" v-model="pro.num" class="sum">
  58. <a href="javascript:;" class="plus" @click="add(pro)">+</a>
  59. </div>
  60. </li>
  61. <li class="list_sum">
  62. <p class="sum_price">¥{{pro.sum}}</p>
  63. </li>
  64. <li class="list_op">
  65. <p class="collect"><a href="javascript:;" class="colBtn">收藏商品</a></p>
  66. <p class="del"><a href="javascript:;" class="delBtn">移除商品</a></p>
  67. <p class="custom"><a href="javascript:;" class="cusBtn">定制商品</a></p>
  68. <div class="custombox">
  69. 测试
  70. </div>
  71. </li>
  72. </ul>
  73. </div>
  74. </div>
  75. <!--底部-->
  76. <div class="bar-wrapper">
  77. <div class="bar-right">
  78. <div class="piece">已选商品<strong class="piece_num">{{this.fetchData.allnum}}</strong></div>
  79. <div class="totalMoney">共计: <strong class="total_text">¥{{this.fetchData.allsum}}</strong></div>
  80. <div class="calBtn"><a href="javascript:;">结算</a></div>
  81. </div>
  82. </div>
  83. </section>
  84. <section class="model_bg"></section>
  85. <section class="my_model">
  86. <p class="title">删除宝贝<span class="closeModel">X</span></p>
  87. <p>您确认要删除该宝贝吗?</p>
  88. <div class="opBtn"><a href="javascript:;" class="dialog-sure">确定</a><a href="javascript:;" class="dialog-close">关闭</a></div>
  89. </section>
  90. </div>

图片描述

大概长这个样子,很普通的一个购物车页面,另外html和css部分不是我写的,是下载的jQuery购物车的demo里的代码,这样比较省事情。

购物车逻辑分析

1.三级选中按钮的实现
2.每件商品总价的变动
3.商品总件数、商品总计价格的变动
4.输入商品数量导致2,3的变动(未实现)

先上数据

  1. data(){
  2. return{
  3. fetchData:{
  4. list:[
  5. {
  6. shop_id:1,
  7. shop_name:'搜猎人艺术生活',
  8. products:[
  9. {
  10. pro_id:101,
  11. text:'洗面奶洗面奶洗面奶洗面奶洗面奶洗面奶洗面奶洗面奶',
  12. price:480,
  13. num:1,
  14. img:'./images/1.png',
  15. sum:480,
  16. checked:false//商品选中状态
  17. },
  18. {
  19. pro_id:102,
  20. text:'花露水花露水花露水花露水花露水花露水花露水花露水',
  21. price:680,
  22. num:1,
  23. img:'./images/2.png',
  24. sum:680,
  25. checked:false
  26. },
  27. {
  28. pro_id:103,
  29. text:'燕麦片燕麦片燕麦片燕麦片燕麦片燕麦片燕麦片燕麦片',
  30. price:380,
  31. num:1,
  32. img:'./images/3.png',
  33. sum:380,
  34. checked:false
  35. }
  36. ],
  37. check:false,//店铺选中状态
  38. choose:0,//商品选中个数
  39. },
  40. {
  41. shop_id:2,
  42. shop_name:'卷卷旗舰店',
  43. products:[
  44. {
  45. pro_id:201,
  46. text:'剃须刀剃须刀剃须刀剃须刀剃须刀剃须刀剃须刀剃须刀',
  47. price:580,
  48. num:1,
  49. img:'./images/4.png',
  50. sum:580,
  51. checked:false
  52. },
  53. {
  54. pro_id:202,
  55. text:'卫生纸卫生纸卫生纸卫生纸卫生纸卫生纸卫生纸卫生纸',
  56. price:780,
  57. num:1,
  58. img:'./images/5.png',
  59. sum:780,
  60. checked:false
  61. }
  62. ],
  63. check:false,
  64. choose:0,
  65. },
  66. {
  67. shop_id:3,
  68. shop_name:'瓜皮的神秘商店',
  69. products:[
  70. {
  71. pro_id:301,
  72. text:'眼镜片眼镜片眼镜片眼镜片眼镜片眼镜片眼镜片眼镜片',
  73. price:180,
  74. num:1,
  75. img:'./images/6.png',
  76. sum:180,
  77. checked:false
  78. },
  79. {
  80. pro_id:302,
  81. text:'凑数的凑数的凑数的凑数的凑数的凑数的凑数的凑数的',
  82. price:280,
  83. num:1,
  84. img:'./images/7.png',
  85. sum:280,
  86. checked:false
  87. }
  88. ],
  89. check:false,
  90. choose:0,
  91. }
  92. ],
  93. status:false,//全选选中状态
  94. allchoose:0,//店铺选中个数
  95. allsum:0,//总计价格
  96. allnum:0//总计数量
  97. }
  98. }
  99. },

意义不明的部分写了注释,其他数据一目了然

单个商品的选中按钮

单个商品的选中按钮很容易实现,一般是添加一个点击方法,值取反。但在购物车中这样的方法是不行的,单个商品的选中以及取消所执行的逻辑有部分不同,所以我选择将其拆分。

  1. choosetrue(item,pro){
  2. pro.checked=true//将商品选中状态改为true
  3. ++item.choose===item.products.length?item.check=true:''//这里执行了两部,选中商品数量先+1,再与该店铺商品数量比较,如果相等就更改店铺选中状态为true
  4. item.check?++this.fetchData.allchoose===this.fetchData.list.length?this.fetchData.status=true:this.fetchData.status=false:''//如果店铺选中状态改为true,选中店铺数量先+1,再与店铺数量比较,如果相等就更改全选选中状态为true
  5. },
  6. choosefalse(item,pro){
  7. pro.checked=false//将商品选中状态改为false
  8. --item.choose//选中商品数量-1
  9. if(item.check){//如果店铺是被选中的,更改店铺选中状态
  10. item.check=false
  11. --this.fetchData.allchoose//并且选中店铺数量-1
  12. }
  13. this.fetchData.status=false//无论之前全选的状态,将其改为false就行
  14. },
  15. choose(item,pro){
  16. !pro.checked?this.choosetrue(item,pro):this.choosefalse(item,pro)
  17. },//这里是绑定到html上的方法,取反是由于你在触发方法的时候取的是之前的状态

相信有的人看了代码还是觉得能把三个函数写在一起,其实我之前就是这么干的,然后就悲剧了,可能是我功底不够。先不管这些。现在分析下店铺全选的逻辑:

  1. 选中之后,店铺下的所有商品选中,并且判断全选按钮是否要选中

  2. 取消选中,店铺下的所有商品取消选中

这是基本逻辑,但如果照这个思路写,用循环将商品状态更改,很轻松,但是还是需要判断是否要选中全选按钮。我们换个思路吧,因为我发现“判断是否要选中全选按钮”已经在之前写过了。店铺选中按钮的前半部分逻辑其实就是choosetrue函数执行了一定的次数,我是这样写的:

单个店铺的选中按钮

  1. shoptrue(item){
  2. item.products.forEach((pro)=>{
  3. pro.checked===false?this.choosetrue(item,pro):''
  4. })
  5. },//循环店铺中的商品,先筛选出目前没选中的商品,给它执行choosetrue函数
  6. shopfalse(item){
  7. item.products.forEach((pro)=>{
  8. pro.checked===true?this.choosefalse(item,pro):''
  9. })
  10. },//循环店铺中的商品,先筛选出目前被选中的商品,给它执行choosefalse函数
  11. shopchoose(item){
  12. !item.check?this.shoptrue(item):this.shopfalse(item)
  13. },

刚才分开写的好处就出现啦,至于为什么要筛选一下,这和之后计算商品总价有关系(如果只是写多选按钮的逻辑,有人会图方便不筛选,比如一小时之前的我)

全选按钮

  1. cartchoose(){
  2. this.fetchData.status=!this.fetchData.status//取反改变状态
  3. this.fetchData.status?this.fetchData.list.forEach((item)=>this.shoptrue(item)):this.fetchData.list.forEach((item)=>this.shopfalse(item))
  4. },//根据取反后的状态进行相应的店铺按钮操作

有人可能发现为什么全选不进行筛选,其实是不需要筛选。之前选中的店铺按钮下的商品状态必然全部是true,只是空跑了一遍,总结起来的逻辑是:没选中的店铺改变状态->没选中的商品改变状态

增加按钮&减少按钮

  1. add(pro){
  2. pro.num++//商品数量+1
  3. pro.sum+=pro.price//商品总价变动
  4. },
  5. reduce(pro){
  6. if(pro.num===1){
  7. pro.num//当商品数量=1,不变
  8. }else{
  9. pro.num--//否则-1
  10. pro.sum-=pro.price//商品总价变动
  11. }
  12. }

这里的逻辑比较简单,不细说。
接下来就是商品总计价格的变动,这里又要分析一下:首先,选中的商品才会影响总计价格的变动,那我们只需要将逻辑写着choosetrue函数中就行,而不需要去一遍一遍循环选中商品的总价格去计算总计价格,稍微调整下。

  1. choosetrue(item,pro){
  2. pro.checked=true
  3. ++item.choose===item.products.length?item.check=true:''
  4. item.check?++this.fetchData.allchoose===this.fetchData.list.length?this.fetchData.status=true:this.fetchData.status=false:''
  5. this.fetchData.allsum+=pro.sum//当触发商品选中按钮,将商品总价格添加到总计价格
  6. },
  7. choosefalse(item,pro){
  8. pro.checked=false
  9. --item.choose
  10. if(item.check){
  11. item.check=false
  12. --this.fetchData.allchoose
  13. }
  14. this.fetchData.status=false
  15. this.fetchData.allsum-=pro.sum//当触发商品取消按钮,将商品总价格从总计价格删去
  16. },
  17. add(pro){
  18. pro.num++
  19. pro.sum+=pro.price
  20. pro.checked?this.fetchData.allsum+=pro.price:this.fetchData.allsum//这里判断下商品的状态决定是不是要改变总计价格
  21. },
  22. reduce(pro){
  23. if(pro.num===1){
  24. pro.num
  25. }else{
  26. pro.num--
  27. pro.sum-=pro.price
  28. pro.checked?this.fetchData.allsum-=pro.price:this.fetchData.allsum//同上
  29. }
  30. }

未完成部分

商品数量的计算,这个淘宝和京东对数量的计算不同,淘宝是商品种类的数量,京东是商品总件数量,逻辑也较简单,跟商品价格后面相应添加就行。
当手动输入商品数量时,价格随之变动,我思考了半天只想到数据监测,但数据嵌套太深了,如果监测fetchData,监测函数会多次无意义触发,监测键盘也不现实,最好的办法是监测num这个数据,但我没继续实验,对watch用的不太熟。有小伙伴有实现方法麻烦告知

更新

之前所有未完成部分已经解决,小伙伴们可以去github看源码。主要包括(商品数量计算,监控输入数字引起价格变动,输入数字的各种限制,避免有人填写负数和小数之类的)

源码

https://github.com/yuyeqianxu...

有bug麻烦告知一声,谢谢

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/83940
推荐阅读
相关标签
  

闽ICP备14008679号