由于我们公司是主营业务是海淘,所以每个项目都是类似淘宝天猫之类的商城,那么购物车就是一个重点开发功能模块。介于之前我都是用jq来写购物车的,这次就用vuejs来写一个购物车。下面我就从全选,数量控制器,运费,商品金额计算等方法来演示一下一个能用在实际场景的购物车是怎么做出来的以及记录一下这次用vuejs踩过的坑。
1.一层数据结构-全选
下面这段代码和vuejs官网里面checkbox绑定很像。不明白的可以直接上vuejs官网看看。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vuejs-全选</title> <style type="text/css"> * { padding: 0; margin: 0; } a { color: #333; text-decoration:none; } </style> </head> <body> <label> <input type="checkbox" v-on:click="chooseAll" v-model="selectArr.length==goodsList.length" /> <span>全选</span> </label> <div v-for="(index, item) in goodsList"> <a href="javascript:;" > <input type="checkbox" :value="index" v-model="selectArr" /> 商品名称:<span v-html="item.name"></span> | 价格:<span v-html="item.price"></span> </a> </div> <label> <input type="checkbox" v-on:click="chooseAll" v-model="selectArr.length==goodsList.length" /> <span>全选</span> </label> <script src="https://cdn.bootcss.com/vue/1.0.7/vue.js"></script> <script> var vue = new Vue({ el : 'body', data : { goodsList : [ { name : '山本汉方1', price : '19.00' }, { name : '山本汉方2', price : '19.00' }, { name : '山本汉方3', price : '19.00' }, { name : '山本汉方4', price : '19.00' }, { name : '山本汉方5', price : '19.00' }, ], selectArr : [] }, ready : function() {}, methods : { chooseAll : function(event) { var oThis = this; oThis.selectArr = []; if ( event.currentTarget.checked ) { oThis.goodsList.forEach(function(item , index) { oThis.selectArr.push(index); }); } console.log(oThis.selectArr); } } }) </script> </body> </html>
2.二层数据结构-全选
一层数据结构的购物车在现实中是很少看到的,比如我们最熟悉的淘宝购物车是按照店铺分的,那么必然是多层的数据结构。这次在写这个二层数据接口的全选,碰到一个很大的坑,一开始我是用了一层数据结构的数据,发现当对象数组里面的某个值改变了,视图竟然没有触发!,所以会造成下面所有的checkbox都被选中了,最上面的那个全选checkbox竟然还是没有被选中。感觉告诉我这是vuejs的坑,后来发现是js的坑。具体可以看这个。方法是百度到了,可是放我这里没有用(应该是版本问题)。于是我就改了数据结构。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vuejs-全选</title> <style type="text/css"> * { padding: 0; margin: 0; } a { color: #333; text-decoration:none; } .goods-item { display: block; } .store-item { margin-bottom: 20px; } </style> </head> <body> <div v-for="(index1, item) in goodsObj"> <p> <span v-html="item.name"></span> <label> <input type="checkbox" v-on:click="chooseShopGoods(index1)" v-model="item.checked" /> <span>全选</span> </label> </p> <a href="javascript:;" v-for="(index, data) in item.list"> <input type="checkbox" v-model="data.checked" v-on:click="choose(index1, index)" /> 商品名称:<span v-html="data.name"></span> | 价格:<span v-html="data.price"></span> </a> </div> <label> <input type="checkbox" v-on:click="chooseAllGoods()" v-model="allChecked" /> <span>全选</span> </label> <script src="https://cdn.bootcss.com/vue/1.0.7/vue.js"></script> <script> var goodsObj = [ { name : '大胖的店', checked : false, list : [ { name : '麻辣二胖', price : 23.00, realStock : 10, fare : 1.5, num : 1, checked : false, }, { name : '香辣二胖', price : 21.00, realStock : 2, fare : 1.5, num : 2, checked : false, }, { name : '红烧二胖', price : 88.00, realStock : 8, fare : 1.5, num : 4, checked : false, } ] }, { name : '二胖的店', checked : false, list : [ { name : '漂亮的裙子', price : 166.00, realStock : 10, fare : 2, num : 1, checked : false, }, { name : '漂亮的短袖', price : 188.00, realStock : 2, fare : 1.5, num : 2, checked : false, }, { name : '漂亮的鞋子', price : 299.00, realStock : 1, fare : 3, num : 1, checked : false, } ] }, { name : '胖胖的店', checked : false, list : [ { name : '福满多', price : 3.00, realStock : 10, fare : .5, num : 10, checked : false, }, { name : '精品卫龙', price : 1.50, realStock : 2, fare : 2, num : 2, checked : false, }, { name : '周长江', price : 2.50, realStock : 3, fare : 5, num : 2, checked : false, } ] }, ]; var vue = new Vue({ el : 'body', data : { goodsObj : goodsObj, allChecked : false }, ready : function() { }, methods : { // 全部商品全选 chooseAllGoods : function() { var flag = true; if ( this.allChecked ) { flag = false; } for ( var i = 0, len = this.goodsObj.length; i < len; i++ ) { this.goodsObj[i]['checked'] = flag; var list = this.goodsObj[i]['list']; for ( var k = 0, len1 = list.length; k < len1; k++ ) { list[k]['checked'] = flag; } } this.allChecked = !this.allChecked; }, // 每个店铺全选 chooseShopGoods : function( index) { var list = this.goodsObj[index]['list'], len = list.length; if ( this.goodsObj[index]['checked'] ) { for (var i = 0; i < len; i++ ) { list[i]['checked'] = false; } } else { for (var i = 0; i < len; i++ ) { list[i]['checked'] = true; } } this.goodsObj[index]['checked'] = !this.goodsObj[index]['checked']; // 判断是否选择所有商品的全选 this.isChooseAll(); }, // 单个选择 choose : function( index1, index) { var list = this.goodsObj[index1]['list'], len = list.length; if ( list[index]['checked'] ) { this.goodsObj[index1]['checked'] = false; this.allChecked = false; list[index]['checked'] = !list[index]['checked']; } else { list[index]['checked'] = !list[index]['checked']; // 判断是否选择当前店铺的全选 var flag = true; for (var i = 0; i < len; i++ ) { if ( list[i]['checked'] == false ) { flag = false; break; } } flag == true ? this.goodsObj[index1]['checked'] = true : this.goodsObj[index1]['checked'] = false; } // 判断是否选择所有商品的全选 this.isChooseAll(); }, // 判断是否选择所有商品的全选 isChooseAll : function() { var flag1 = true; for ( var i = 0, len = this.goodsObj.length; i < len; i++ ) { if ( this.goodsObj[i]['checked'] == false ) { flag1 = false; break; } } flag1 == true ? this.allChecked = true : this.allChecked = false; }, } }) </script> </body> </html>
3.一层数据结构-数量选择器