摘要:最近后端的同事要我写一个购物车,一开始我用写,但写着写着发现逻辑太混乱了,写不下去。所以我想着用来实现一个。但在购物车中这样的方法是不行的,单个商品的选中以及取消所执行的逻辑有部分不同,所以我选择将其拆分。
最近后端的同事要我写一个购物车,一开始我用jQuery写,但写着写着发现逻辑太混乱了,写不下去。最后花了五分钟找了个demo丢给了他。后来我不甘心,毕竟水平菜还不求上进就完蛋了。所以我想着用vue来实现一个。
本来想看看别人的代码,但搜索了下github发现,能找到的购物车都是两级分类的。而京东、淘宝之流都是三级分类的: 1. 全选 2. 店铺全选 3. 商品选中
这样的貌似才有实用价值
html部分,不过多赘述
- 全选
- 商品信息
- 商品参数
- 单价
- 数量
- 金额
- 操作
删除宝贝X
您确认要删除该宝贝吗?
大概长这个样子,很普通的一个购物车页面,另外html和css部分不是我写的,是下载的jQuery购物车的demo里的代码,这样比较省事情。
购物车逻辑分析1.三级选中按钮的实现
2.每件商品总价的变动
3.商品总件数、商品总计价格的变动
4.输入商品数量导致2,3的变动(未实现)
data(){ return{ fetchData:{ list:[ { shop_id:1, shop_name:"搜猎人艺术生活", products:[ { pro_id:101, text:"洗面奶洗面奶洗面奶洗面奶洗面奶洗面奶洗面奶洗面奶", price:480, num:1, img:"./images/1.png", sum:480, checked:false//商品选中状态 }, { pro_id:102, text:"花露水花露水花露水花露水花露水花露水花露水花露水", price:680, num:1, img:"./images/2.png", sum:680, checked:false }, { pro_id:103, text:"燕麦片燕麦片燕麦片燕麦片燕麦片燕麦片燕麦片燕麦片", price:380, num:1, img:"./images/3.png", sum:380, checked:false } ], check:false,//店铺选中状态 choose:0,//商品选中个数 }, { shop_id:2, shop_name:"卷卷旗舰店", products:[ { pro_id:201, text:"剃须刀剃须刀剃须刀剃须刀剃须刀剃须刀剃须刀剃须刀", price:580, num:1, img:"./images/4.png", sum:580, checked:false }, { pro_id:202, text:"卫生纸卫生纸卫生纸卫生纸卫生纸卫生纸卫生纸卫生纸", price:780, num:1, img:"./images/5.png", sum:780, checked:false } ], check:false, choose:0, }, { shop_id:3, shop_name:"瓜皮的神秘商店", products:[ { pro_id:301, text:"眼镜片眼镜片眼镜片眼镜片眼镜片眼镜片眼镜片眼镜片", price:180, num:1, img:"./images/6.png", sum:180, checked:false }, { pro_id:302, text:"凑数的凑数的凑数的凑数的凑数的凑数的凑数的凑数的", price:280, num:1, img:"./images/7.png", sum:280, checked:false } ], check:false, choose:0, } ], status:false,//全选选中状态 allchoose:0,//店铺选中个数 allsum:0,//总计价格 allnum:0//总计数量 } } },
意义不明的部分写了注释,其他数据一目了然
单个商品的选中按钮单个商品的选中按钮很容易实现,一般是添加一个点击方法,值取反。但在购物车中这样的方法是不行的,单个商品的选中以及取消所执行的逻辑有部分不同,所以我选择将其拆分。
choosetrue(item,pro){ pro.checked=true//将商品选中状态改为true ++item.choose===item.products.length?item.check=true:""//这里执行了两部,选中商品数量先+1,再与该店铺商品数量比较,如果相等就更改店铺选中状态为true item.check?++this.fetchData.allchoose===this.fetchData.list.length?this.fetchData.status=true:this.fetchData.status=false:""//如果店铺选中状态改为true,选中店铺数量先+1,再与店铺数量比较,如果相等就更改全选选中状态为true }, choosefalse(item,pro){ pro.checked=false//将商品选中状态改为false --item.choose//选中商品数量-1 if(item.check){//如果店铺是被选中的,更改店铺选中状态 item.check=false --this.fetchData.allchoose//并且选中店铺数量-1 } this.fetchData.status=false//无论之前全选的状态,将其改为false就行 }, choose(item,pro){ !pro.checked?this.choosetrue(item,pro):this.choosefalse(item,pro) },//这里是绑定到html上的方法,取反是由于你在触发方法的时候取的是之前的状态
相信有的人看了代码还是觉得能把三个函数写在一起,其实我之前就是这么干的,然后就悲剧了,可能是我功底不够。先不管这些。现在分析下店铺全选的逻辑:
选中之后,店铺下的所有商品选中,并且判断全选按钮是否要选中
取消选中,店铺下的所有商品取消选中
这是基本逻辑,但如果照这个思路写,用循环将商品状态更改,很轻松,但是还是需要判断是否要选中全选按钮。我们换个思路吧,因为我发现“判断是否要选中全选按钮”已经在之前写过了。店铺选中按钮的前半部分逻辑其实就是choosetrue函数执行了一定的次数,我是这样写的:
单个店铺的选中按钮shoptrue(item){ item.products.forEach((pro)=>{ pro.checked===false?this.choosetrue(item,pro):"" }) },//循环店铺中的商品,先筛选出目前没选中的商品,给它执行choosetrue函数 shopfalse(item){ item.products.forEach((pro)=>{ pro.checked===true?this.choosefalse(item,pro):"" }) },//循环店铺中的商品,先筛选出目前被选中的商品,给它执行choosefalse函数 shopchoose(item){ !item.check?this.shoptrue(item):this.shopfalse(item) },
刚才分开写的好处就出现啦,至于为什么要筛选一下,这和之后计算商品总价有关系(如果只是写多选按钮的逻辑,有人会图方便不筛选,比如一小时之前的我)
全选按钮cartchoose(){ this.fetchData.status=!this.fetchData.status//取反改变状态 this.fetchData.status?this.fetchData.list.forEach((item)=>this.shoptrue(item)):this.fetchData.list.forEach((item)=>this.shopfalse(item)) },//根据取反后的状态进行相应的店铺按钮操作
有人可能发现为什么全选不进行筛选,其实是不需要筛选。之前选中的店铺按钮下的商品状态必然全部是true,只是空跑了一遍,总结起来的逻辑是:没选中的店铺改变状态->没选中的商品改变状态
增加按钮&减少按钮add(pro){ pro.num++//商品数量+1 pro.sum+=pro.price//商品总价变动 }, reduce(pro){ if(pro.num===1){ pro.num//当商品数量=1,不变 }else{ pro.num--//否则-1 pro.sum-=pro.price//商品总价变动 } }
这里的逻辑比较简单,不细说。
接下来就是商品总计价格的变动,这里又要分析一下:首先,选中的商品才会影响总计价格的变动,那我们只需要将逻辑写着choosetrue函数中就行,而不需要去一遍一遍循环选中商品的总价格去计算总计价格,稍微调整下。
choosetrue(item,pro){ pro.checked=true ++item.choose===item.products.length?item.check=true:"" item.check?++this.fetchData.allchoose===this.fetchData.list.length?this.fetchData.status=true:this.fetchData.status=false:"" this.fetchData.allsum+=pro.sum//当触发商品选中按钮,将商品总价格添加到总计价格 }, choosefalse(item,pro){ pro.checked=false --item.choose if(item.check){ item.check=false --this.fetchData.allchoose } this.fetchData.status=false this.fetchData.allsum-=pro.sum//当触发商品取消按钮,将商品总价格从总计价格删去 }, add(pro){ pro.num++ pro.sum+=pro.price pro.checked?this.fetchData.allsum+=pro.price:this.fetchData.allsum//这里判断下商品的状态决定是不是要改变总计价格 }, reduce(pro){ if(pro.num===1){ pro.num }else{ pro.num-- pro.sum-=pro.price pro.checked?this.fetchData.allsum-=pro.price:this.fetchData.allsum//同上 } }未完成部分
商品数量的计算,这个淘宝和京东对数量的计算不同,淘宝是商品种类的数量,京东是商品总件数量,逻辑也较简单,跟商品价格后面相应添加就行。
当手动输入商品数量时,价格随之变动,我思考了半天只想到数据监测,但数据嵌套太深了,如果监测fetchData,监测函数会多次无意义触发,监测键盘也不现实,最好的办法是监测num这个数据,但我没继续实验,对watch用的不太熟。有小伙伴有实现方法麻烦告知
之前所有未完成部分已经解决,小伙伴们可以去github看源码。主要包括(商品数量计算,监控输入数字引起价格变动,输入数字的各种限制,避免有人填写负数和小数之类的)
源码https://github.com/yuyeqianxu...
有bug麻烦告知一声,谢谢
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/89823.html
摘要:专业人员如何在日常故障排除中苦苦挣扎,如果您的组织要么关注,要么雇佣大量开发人员,请确保您关注他们的工作量,要么面对出走的客户。DevOps专业人员如何在日常故障排除中苦苦挣扎,Grindtweet如果您的组织要么关注DevOps,要么雇佣大量开发人员,请确保您关注他们的工作量,要么面对出走的客户。这是IT管理软件提供商Solarwinds的主要发现。在其最新的调查报告中,对美国和加拿大的3...
摘要:贪吃蛇并不是通过操作来完成移动的,而是通过记录贪吃蛇的路径来将身体渲染出来。目前没有内置的操作符判断对象的内容是否相同。 还是用的vue,本来以为不合适,但想法错了。贪吃蛇并不是通过操作dom来完成移动的,而是通过记录贪吃蛇的路径来将身体渲染出来。 一般移动元素,我们都是变动它的css达到目的,但我在写贪吃蛇的时候发现这样很难以实现,参考了网上的资源,发现大部分人是通过记录贪吃蛇的路径...
摘要:中国的行业的蓬勃发展,蛋糕之大,让所有行业从业者的收入总体处于行业前列,可比拟的只有金融行业一个不创造财富,只分配财富的行业。每天收到十几份简历,却招聘不到合适的人。很多小伙伴冷门专业,普通学校,毕业了工作几年了月薪还是几千块,这就是现状。 中国的IT行业因为有人口福...
阅读 3028·2021-11-22 09:34
阅读 3564·2021-08-31 09:45
阅读 3735·2019-08-30 13:57
阅读 1652·2019-08-29 15:11
阅读 1664·2019-08-28 18:04
阅读 3190·2019-08-28 17:59
阅读 1538·2019-08-26 13:35
阅读 2172·2019-08-26 10:12