100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > vue实现完整的购物车功能(包括单选全选 删除商品和结算商品功能)

vue实现完整的购物车功能(包括单选全选 删除商品和结算商品功能)

时间:2024-04-26 21:41:08

相关推荐

vue实现完整的购物车功能(包括单选全选 删除商品和结算商品功能)

首先来看看效果图

预览地址:http://xy.xxiaoyuan.top/demo/shopCart/#/

项目开始之前需要选安装好node跟vue和vue-cli

如果还没安装的可以看这里(mac环境下的)/weixin_39644462/article/details/86302579

1. 首先创建一个vue项目(命令行如下)

vue init webpack shopcart

然后可以一路回车或者Y

2. 创建成功后进入到shopcart目录

cd shopcart

3. 安装项目所需要的依赖

我这项目用到axios请求自己写点json模拟数据,UI框架用到饿了么的Mint-UI框架,使用less作为css预处理器

//安装axiosnpm install axios --save//安装Mint-UI_npm install mint-ui --save//安装lessnpm install less less-loader --save-dev

好了,可以先运行项目看看

npm run dev

如果浏览器没有自动打开浏览器的话,可以自己手动在浏览器输入localhost:8080 ,或者设置/config/index.js(如下图)

默认样式效果

下面配置一下安装的依赖

配置axios 和 Mint-UI (打开/src/main.js)

配置less(在build/webpack.base.conf.js 的module.exports.module.rules 里面添加如下代码)

{test: /\.less$/,loader: 'style-loader!css-loader!less-loader'}

为了移动端自配,将引入外部flexible.js进行适配,将flexible.js放在/static/js/目录下,然后在/src/main.js下引入

import '../static/js/flexible.js'

并在/src创建一个目录styles(mixin.less用来做计算rem尺寸,源码文章后面有)

接下来就真正的搞事情了/components/shopCart.vue

<template><div class="page"><header><h3>购物车</h3></header><div class="shop_car_body"><ul><li v-for="(item, index) in list"><div class="car_list_top"><div class="car_list_t_l"><!-- 选择商品 --><div class="input_check"><span class="ico_gou":class="{'ico_gou_on':item.checked}" @click="selectGoods(item)"></span></div><!-- 选择商品 end --><P>商家: {{item.shop_name}}</P></div><div class="car_list_t_r"><p class="ico_del" @click="delGoods(item.goods_id,index)"></p></div></div><div class="car_list_center"><div class="car_list_c_l"><img :src="'http:'+item.goods_img" alt=""></div><div class="car_list_c_r"><p>{{item.goods_name}}</p><div class="goods_intor"><p>¥{{item.price}}</p><p class="select_num_input"><span class="ico_sub" @click="sub(item.sales_num,index)"></span><input type="number" :value="item.sales_num" disabled><span class="ico_plus" @click="plus(item.sales_num,index)"></span></p></div></div></div></li></ul><div class="car_footer"><div class="car_footer_l" v-show="!checkAllFlag"><span class="ico_gou" @click="checkAll(true)"></span><p>全选</p></div><div class="car_footer_l" v-show="checkAllFlag"><span class="ico_gou_on" @click="checkAll(false)"></span><p>取消全选</p></div><div class="car_footer_r"><span>合计:{{$setNum.Dec(totalMoney,2)}}</span><p @click="toDo()">结算({{checkNum}})</p></div></div></div></div></template><script>import { Toast, Indicator, MessageBox} from 'mint-ui'export default {data () {return {list:[],selectId:[], //选中的商品idtotalMoney: 0, //总价checkNum: 0, //选择的商品数量(结算需要显示的数量)checkAllFlag:false, //是否全选}},computed: {},methods: {// 点击结算toDo(){if(this.checkNum <= 0){Toast('先选中需要结算的商品');}else{// 结算选中的商品var isList = [];for(var i in this.list){if(this.list[i].checked){isList.push(this.list[i]);}}console.log(isList);}},// (单选)选择商品selectGoods(item){//判断是否未定义,如果没点击过按钮是没有注册的,则需要先注册checked属性if(typeof item.checked =='undefined'){this.$set(item,"checked",true);this.checkNum ++; //结算需要显示的数量}else{// 如果已经注册,则设置checked否(这里不能设置为false,因为当已经注册过之后再点击为flase,那么再点击一次则为true)item.checked = !item.checked;item.checked ? this.checkNum ++ : this.checkNum --;}// 求总价this.totalPrice();// 当所有的商品都选择的时候,自动默认为全选this.list.length == this.checkNum ? this.checkAll(true) : this.checkAllFlag = false;},// 全选与取消全选,点击全选时flag为true,取消时为falsecheckAll(flag){this.checkAllFlag = flag;var _this = this;flag ? this.checkNum = this.list.length : this.checkNum = 0;this.list.forEach(function(item,index){if(typeof item.checked == 'undefined'){//也要防止未定义_this.$set(item,"checked",_this.checkAllFlag);//通过set来给item添加属性checked}else{item.checked = _this.checkAllFlag;}});this.totalPrice();},// 求总价totalPrice(){var _this = this;this.totalMoney = 0;this.list.forEach((item,index)=>{if(item.checked){_this.totalMoney += this.$setNum.accMul(item.price,item.sales_num);}});},// 删除商品delGoods(id,index){MessageBox.confirm('',{title:'',message:'确定删除该商品吗?',confirmButtonText:'确定',cancelButtonText:'取消'}).then(action => {if (action == 'confirm') {// 刷新类表this.getList();// 取消全选this.checkAll(false);}}).catch(error =>{});},// 数量减方法sub(num,index){if(parseInt(num) <= 1){this.list[index].sales_num = 1;}else{this.list[index].sales_num = parseInt(this.list[index].sales_num) - 1;}this.totalPrice();},// 数量加方法plus(num,index){this.list[index].sales_num = parseInt(this.list[index].sales_num) + 1;this.totalPrice();},// 获取购物车列表getList(){var _this = this;this.$http.get("/static/data/data.json").then(function(res){_this.list = res.data.list;});}},mounted(){this.getList();}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped lang="less">@import "./../styles/index.less";.page{.mt(88);.mb(110);.pt(20);}header{.h(88);.lh(88);background: @base-color;color: #fff;.fs(32);text-align: center;position: fixed;.left(0);.top(0);width: 100%;z-index: 100;}.shop_car_body{.w-calc(48);.ml(24);ul{li{.b-radius(16);background: #fff;.mb(20);.fs(28);.padding(0,24);.pb(24);.car_list_top{.fs(30);display: flex;justify-content: space-between;align-items: center;.padding(24,0);.car_list_t_l{display: flex;justify-content: flex-start;align-items: center;.input_check{position: relative;.mr(20);.w(40);.h(40);span{display: block;position: absolute;.top(4);.left(4);.w(36);.h(36);.bgs(36,36);}}}.car_list_t_r{p.ico_del{.w(36);.h(40);.bgs(36,40);}}}.car_list_center{display: flex;justify-content: flex-start;.car_list_c_l{img{display: block;.w(160);.h(160);object-fit: cover;}}.car_list_c_r{.ml(20);display: flex;flex-direction: column;justify-content: space-around;align-items: flex-start;.w-calc(140);p:nth-child(1){text-align: left;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;}.goods_intor{display: flex;justify-content: space-between;align-items: center;width: 100%;.select_num_input{display: flex;justify-content: center;align-items: center;span{display: flex;justify-content: center;align-items: center;@ico_s:40;.w(@ico_s);.h(@ico_s);.bgs(@ico_s,@ico_s);&:active{opacity: .5;}}input[type=number]{.w(60);text-align: center;background: none;}}}}}}}// footer.car_footer{.border-top(2,#eee);position: fixed;.left(0);.bottom(0);.w-calc(48);background: #fff;.h(88);.fs(30);display: flex;justify-content: space-between;align-items: center;.padding(0,24);.car_footer_l{.fs(28);color: @base-color;display: flex;justify-content: flex-start;align-items: center;p{.ml(20);}span{display: block;.w(36);.h(36);.bgs(36,36);}}.car_footer_r{display: flex;justify-content: flex-end;align-items: center;span{display: block;.mr(30);}p{display: flex;justify-content: center;align-items: center;color: #fff;.h(60);.padding(0,30);.b-radius(30);background: linear-gradient(45deg, #ff6924, #fe8701);}}}}</style>

主要代码在上面,下面讲解一下主要部分

获取列表数据(因为购物车列表数据是通过自己模拟json数据来实现的,模拟的数据放在/static/data/data.json)

{"list": [{"classify_id": 1,"goods_img": "///imgextra/i2/726671139/O1CN01UsYSFL1KHhdcGkTfo_!!726671139.jpg_400x400.jpg","goods_name": "连衣裙ins夏chic新款很仙的法国小众吊带网纱超仙a字裙两件套","goods_id": 61,"shop_name": "恋上公主","sales_num": 1,"price": "105.00"},{"classify_id": 2,"goods_img": "///imgextra/i3/726671139/O1CN01P4vwli1KHhdYOfl9j_!!726671139.jpg_400x400.jpg","goods_name": "防晒衬衫女长袖薄款设计感小众百搭外穿新款超薄透气雪纺衬衣","goods_id": 62,"shop_name": "恋上公主","sales_num": 2,"price": "116.00"},{"classify_id": 2,"goods_img": "///imgextra/i1/726671139/O1CN010EFA6U1KHhdODcpz0_!!726671139.jpg_400x400.jpg","goods_name": "网红时尚连衣裙很仙的夏款网纱小清新温柔波点吊带T恤裙套装","goods_id": 63,"shop_name": "恋上公主","sales_num": 3,"price": "129.00"},{"classify_id": 4,"goods_img": "///imgextra/i4/726671139/O1CN01nonA501KHhctJZ7Tk_!!726671139.jpg_400x400.jpg","goods_name": "新款衬衫女时尚洋气超仙设计感小众长袖收腰雪纺韩版chic衬衣","goods_id": 64,"shop_name": "恋上公主","sales_num": 3,"price": "69.00"}]}

然后通过axios的get请求获取到数据(在methods钩子里写getList方法获取,在mounted钩子初始化)

数量加和数量减的方法

选择商品(单选)

下面代码有注释,应该是比较详细的了

全选

求总价(查找列表,如果存在checked == true,则将其价格剩余数量,下面用到了$setNum.accMul(int1,int2),这个方法是自己封装的一个乘法方法,因为在js中的浮点类型相乘并不能完全得到准确的数据,会存在一定的误差,该方法在/src/assets/js/setDec.js里)

删除商品

点击结算(可以在控制台查看,选中的商品)

最后打包,修改/config/index.js文件下的module.exports下的build的assetsPublicPath,设置为'./'

最后预览地址:http://xy.xxiaoyuan.top/demo/shopCart/#/

源码下载地址在gitHud:/YanGo520/shopCart(源码好像没有修改打包后的相对静态资源文件,可以参考上面修改assetsPublicPath为 './' )

码云地址:/yango520/shopCart

最后允许我打个小广告(虽然很多猿兄没女朋友这是种生物[/滑稽脸]):恋上公主(里面的衣服贼漂亮)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。