博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用vue实现一个淘宝购物车,给和我一样苦苦挣扎的前端小白(更新)
阅读量:6169 次
发布时间:2019-06-21

本文共 10801 字,大约阅读时间需要 36 分钟。

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

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

这样的貌似才有实用价值

html部分,不过多赘述

  • 全选
  • 商品信息
  • 商品参数
  • 单价
  • 数量
  • 金额
  • 操作
已选商品
{ {this.fetchData.allnum}}
共计:
¥{ {this.fetchData.allsum}}

删除宝贝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上的方法,取反是由于你在触发方法的时候取的是之前的状态

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

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

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

这是基本逻辑,但如果照这个思路写,用循环将商品状态更改,很轻松,但是还是需要判断是否要选中全选按钮。我们换个思路吧,因为我发现“判断是否要选中全选按钮”已经在之前写过了。店铺选中按钮的前半部分逻辑其实就是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看源码。主要包括(商品数量计算,监控输入数字引起价格变动,输入数字的各种限制,避免有人填写负数和小数之类的)

源码

有bug麻烦告知一声,谢谢

转载地址:http://zunba.baihongyu.com/

你可能感兴趣的文章
PHP 实战之设计模式:PHP 中的设计模式
查看>>
使用 Python 创建你自己的 Shell(下)
查看>>
Linux命令行–理解Linux文件权限(转)
查看>>
[Hadoop大数据]——Hive连接JOIN用例详解
查看>>
高可用性、负载均衡的mysql集群解决方案
查看>>
互联网直播平台架构案例一
查看>>
mysql++ result
查看>>
用正则把url解析为对象
查看>>
PHP与Java进行通信的实现方法
查看>>
apache 图片防盗链
查看>>
利用shell脚本自动获取awr报表
查看>>
分块算法
查看>>
zabbix3.2 报错 Database error
查看>>
中控考勤仪IFace302多线程操作时无法订阅事件
查看>>
C++ 函数适配器
查看>>
两根筷子好吃饭
查看>>
Android 中 java 与 webview 的交互
查看>>
undefined reference to
查看>>
用户在notes和shmail禁用离开办公室后,为何离开办公室代理依然运行
查看>>
读<<CLR via C#>>总结(1) dotNet平台下源代码是如何生成应用程序的
查看>>