在上一版代码基础上,增加了模态框弹窗效果,新增点击删除,全部删除按钮,结算时显示模态框提示消息,增加分类已加入,未加入,全部,分类按钮,用到了$ref对DOM操作,0表示未导入,1表示已加入,all表示全部列表,这个功能代码示例如下:
页面部分用到了v-show v-if条件作逻辑判断,动态消息提示部分让我深刻体会到了Vue 基于数据驱动是这样的方便,对DOM操作时,开始考虑到用指令去实现,后来试了几次都没有找到合适的方式,最后找到了$ref去操作DOM.Vue还有一些比如路由,组件,后续会用到的知识现在还有待学习,希望能完成的尽善尽美。
shopping_cart.js
1 //var newProduct = {name:'',color:'',price:0,amount:0,default_nums:1,add_nums:0,ischange:'btn-danger'}; 2 // 商品列表json 3 var goodsTable = new Vue({ 4 el: '.content', 5 data: { 6 // 用于保存每件商品的对象 7 goodItem: {}, 8 // 用于保存用户添加到购车的商品数组 9 buyLists: [], 10 //要删除的索引 11 nowIndex: -100, 12 //消息 13 msg: "", 14 //要从数组中移除的商品名 15 nm: "", 16 //是否结算 17 suc: false, 18 // 19 isAdd: true, 20 // 默认的商品列表 21 goods: [ 22 {name:'iphone 7 plus 手机',color:'银色',price:100,amount:0,default_nums:1,add_nums:0}, 23 {name:'华硕笔记本电脑',color:'黑色',price:100,amount:0,default_nums:1,add_nums:0}, 24 {name:'九阳电热水瓶5L',color:'白色',price:100,amount:0,default_nums:1,add_nums:0} 25 ], 26 //用于增加新商品到列表 27 newProduct: {name:'',color:'',price:0,amount:0,default_nums:1,add_nums:0,ischange:'btn-danger'}, 28 }, 29 computed: { 30 count: function() { 31 var num = 0; 32 for(var i in this.goods){ 33 num += parseInt(this.goods[i].default_nums); 34 } 35 return num; 36 }, 37 total: function() { 38 var total = 0; 39 for(var i in this.goods){ 40 total += parseInt(this.goods[i].price * this.goods[i].default_nums); 41 } 42 return total; 43 }, 44 addShoppingNum: function() { 45 var addShoppingNum = 0; 46 for(var i in this.goods){ 47 addShoppingNum += this.goods[i].add_nums; 48 } 49 return addShoppingNum; 50 }, 51 costPaid: function() { 52 var costPaid = 0; 53 for(var i in this.goods){ 54 costPaid += parseInt(this.goods[i].price * this.goods[i].add_nums); 55 } 56 return costPaid; 57 } 58 }, 59 methods: { 60 reduce: function(good) { 61 if (good.default_nums <= 1) return; 62 good.default_nums --; 63 //good.ischange = 'btn-danger'; 64 }, 65 /*addNum: function(good) { 66 good.default_nums += 1; 67 //good.ischange = 'btn-danger'; 68 },*/ 69 addProduct: function() { 70 //var len = this.goods.length; 71 //追加商品 72 //this.goods.push(Object.assign({},this.goods[len-1]));//浅拷贝 73 //this.goods.push(Object.assign({}, this.newProduct));//浅拷贝 74 this.goods.push(JSON.parse(JSON.stringify(this.newProduct)));//深拷贝 75 }, 76 removeProduct: function(index,nm) { 77 //删除商品 78 if(index == -2){ 79 this.goods = []; 80 this.buyLists = []; 81 }else{ 82 this.goods.splice(index,1); 83 //删除buyLists中的商品 84 for(var i=this.buyLists.length-1; i>=0; i--){ 85 if(this.buyLists[i].name == nm){ 86 this.buyLists.splice(i,1); 87 } 88 } 89 } 90 }, 91 /*showFunction: function(n) { 92 if(n){ 93 //已结算 94 for(var i in this.goods){ 95 if(this.goods[i].default_nums == this.goods.add_nums[i]){ 96 this.goods[i].name 97 } 98 } 99 }else{ 100 //未结算 101 102 103 } 104 },*/ 105 addToCar(good) { 106 if(good.add_nums == good.default_nums) return; 107 good.add_nums = good.default_nums; 108 //good.ischange = 'btn-success'; 109 this.goodItem = {name: good.name, nums: good.add_nums}; 110 // 创建用户当前添加的商品对象 111 // 开始向数组中提添加当前物品,这里存在3种情况 112 // 1、用户未添加过该商品,则直接向数组中push 113 // 2、用于已经添加了该商品、并且未做购买数量修改,则不向数组中添加 114 // 3、用于已经添加了该商品、但是修改了购买数量,直接替换数组中的该商品对象 115 var index = this.buyLists.findIndex((value, index, arr) => { 116 return value.name === this.goodItem.name; 117 }); 118 //Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 119 index === -1 ? this.buyLists.push(this.goodItem) : Object.assign(this.buyLists[index], this.goodItem); 120 }, 121 balance() { 122 if(this.suc){ 123 124 console.log(this.buyLists); 125 if(this.buyLists.length != 0){ 126 this.msg = '结算成功!'; 127 console.log("结算成功!"); 128 }else{ 129 this.msg = '购物车还没有加入商品,请先加入到购物车!'; 130 console.log("购物车还没有加入商品,请先加入到购物车!"); 131 } 132 } 133 }, 134 showFunction(n) {//$ref 操作DOM 135 if(n == '0'){ 136 for(var i in this.goods){ 137 if(this.goods[i].default_nums == this.goods[i].add_nums){ 138 this.$refs.good[i].style.display = "none"; 139 }else{ 140 this.$refs.good[i].style.display = ""; 141 } 142 } 143 }else if(n=='all'){ 144 for(var i in this.goods){ 145 this.$refs.good[i].style.display = ""; 146 } 147 }else if(n == '1'){ 148 for(var i in this.goods){ 149 if(this.goods[i].default_nums == this.goods[i].add_nums){ 150 this.$refs.good[i].style.display = ""; 151 }else{ 152 this.$refs.good[i].style.display = "none"; 153 } 154 } 155 } 156 } 157 }, 158 updated(){//数据更新完成后 159 //this.$refs.good[0].style.display == "none"; 160 console.log(this.$refs.good); 161 console.log(this.$el); 162 } 163 })
shopping_cart.html
1 <!DOCTYPE html> 2 <html lang="zh-en"> 3 <head> 4 <title>添加购物车商品列表</title> 5 <meta charset="utf-8" /> 6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" /> 7 <style type="text/css"> 8 [v-cloak]{ /*防止页面闪烁*/ 9 display: none !important; 10 } 11 .content{ 12 width: 1000px; 13 margin: 100px auto; 14 } 15 .sWidth{ 16 width:50px; 17 height:20px; 18 } 19 .hide{ 20 display: none; 21 } 22 </style> 23 </head> 24 <body> 25 26 <div class="content"> 27 <!-- 商品列表 --> 28 <table class="table table-bordered" id="goods-table" v-cloak> 29 <thead> 30 <th>序号</th> 31 <th>商品名称</th> 32 <th>颜色</th> 33 <th>数量</th> 34 <th>单价</th> 35 <th>金额</th> 36 <th>操作</th> 37 </thead> 38 <tbody> 39 <tr v-for="(good, $index) in goods" ref="good"> 40 <td>{{ $index+1 }}</td> 41 <td><input v-model.lazy="good.name"></td> 42 <td><input v-model.lazy="good.color" class="sWidth"></td> 43 <td> 44 <button v-on:click="reduce(good)">-</button> 45 <input type="text" type="number" v-model.number="good.default_nums"/> 46 <button v-on:click="good.default_nums += 1">+</button> 47 </td> 48 <td> 49 <input class="sWidth" v-model.number="good.price"></span> 50 </td> 51 <td> 52 <span>{{good.price*good.default_nums}}</span> 53 </td> 54 <td> 55 <button class="btn btn-sm" v-bind:class="good.default_nums == good.add_nums ? 'btn-success' : 'btn-danger'" v-on:click="addToCar(good)">加入购物车</button> 56 <span>已加入购物车的该商品数量:</span> 57 <span>{{good.add_nums}}</span> 58 <button class="btn btn-sm btn-danger" data-toggle="modal" data-target="#layer" v-on:click="nowIndex=$index,msg='确认删除吗?',nm=good.name">删除</button> 59 </td> 60 </tr> 61 </tbody> 62 <tfoot> 63 <tr> 64 <td colspan="7"> 65 <button class="btn btn-danger" v-on:click="addProduct()">添加商品</button> 66 67 <button class="btn btn-sm btn-danger pull-right" data-toggle="modal" data-target="#layer" v-on:click="nowIndex=-2,msg='确认全部删除吗?'">全部删除</button> 68 </td> 69 70 </tr> 71 <tr> 72 <td colspan="6"> 73 <span class="modal-title">{{msg}}</span> 74 <span v-show="msg==''">合计数量{{count}}件</span> 75 <span v-show="msg==''">合计金额{{total}}元</span> 76 <b v-show="msg!='已加入' && msg!='未加入' && msg!='结算成功!'">||</b> 77 <span v-show="msg=='未加入'">购物车{{count - addShoppingNum}}件</span> 78 <span v-show="msg!='未加入'">购物车{{addShoppingNum}}件</span> 79 <span v-show="msg!='未加入'">花费{{costPaid}}元</span> 80 </td> 81 <td colspan="1"> 82 <button class="btn btn-danger pull-left" v-on:click="msg='',showFunction('all')">全部</button> 83 <button class="btn btn-danger pull-left" v-on:click="msg='已加入',showFunction('1')">已加入</button> 84 <button class="btn btn-danger pull-left" v-on:click="msg='未加入',showFunction('0')">未加入</button> 85 <button class="btn btn-danger pull-right" data-toggle="modal" data-target="#layer" v-on:click="suc=true,msg='是否结算?'">结算</button> 86 </td> 87 </tr> 88 </tfoot> 89 </table> 90 91 <!--模态框 弹出框--> 92 <div role="dialog" class="modal fade bs-example-modal-sm" id="layer"> 93 <div class="modal-dialog"> 94 <div class="modal-content"> 95 <div class="modal-header"> 96 <button type="button" class="close" data-dismiss="modal"> 97 <span>×</span> 98 </button> 99 <h4 class="modal-title">{{msg}}</h4> 100 </div> 101 <div class="modal-body text-right"> 102 <button data-dismiss="modal" class="btn btn-default btn-sm" v-on:click="suc=false,msg=''">取消</button> 103 <button data-dismiss="modal" class="btn btn-danger btn-sm" v-on:click="removeProduct(nowIndex,nm),msg=''" v-if="!suc">确认</button> 104 <button data-dismiss="modal" class="btn btn-danger btn-sm" v-on:click="balance()" v-else>结算</button> 105 </div> 106 </div> 107 </div> 108 </div> 109 110 </div> 111 <!-- js --> 112 <script type="text/javascript" src="js/vue.js"></script> 113 <script type="text/javascript" src="js/shopping_cart.js"></script> 114 <script src="js/jquery-1.8.1.min.js"></script> 115 <script src="js/bootstrap.js"></script> 116 </body> 117 </html>
效果图如下:
删除效果
全部删除
已加入购物车
未加入购物车
结算提示
结算成功提示
最后,欢迎大家对我做的这个小练习,多多指正,共同进步。
git>https://github.com/double2018/shopping_cart/