都说vue的双向数据绑定好用,自己用了下,感觉做购物车没想象中好用。自己的实现如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/vue.js"></script> <script src="js/axios.min.js"></script> </head> <body> <div id="app"> <input type="checkbox" v-model="checkedAll"> <ul> <li v-for="(item,index) in shopingcart"> <input type="checkbox" v-model="checkedNames[index]"><img :src="item.imgUrl" alt=""> <div><span class="price">¥{{item.unitPrice}}</span></div> <div class="item-amount "><a href="#" class="J_Minus no-minus" @click="minus(index)">-</a><input @change="num(event,index)" type="text" v-model="item.quantity" class="text text-amount J_ItemAmount" autocomplete="off"><a href="#" class="J_Plus plus" @click="add(index)">+</a> </div> <div class="td-inner"><em tabindex="0" class="J_ItemSum number">¥{{Math.ceil(parseFloat(item.unitPrice*item.quantity)*10)/10}}</em> <div class="J_ItemLottery"></div> <div class="weight" data-spm-anchor-id="a1z0d.6639537.1997196601.i2.4cf574843pYndQ"> ({{Math.ceil(parseFloat(item.weight*item.quantity)*100)/100}}kg) </div> </div> </li> </ul> <span>Checked names: {{ checkedNames }}</span> <input type="checkbox" v-model="checkedAll"> <span>{{goodTotal}}</span>件 合计:<span>{{priceAll}}</span> 结算 </div> <script> var Data = { test: [ { imgUrl: 'https://img.alicdn.com/bao/uploaded/i2/725677994/TB1Z1mzXMmTBuNjy1XbXXaMrVXa_!!0-item_pic.jpg_80x80.jpg', unitPrice: 29.90, weight: 0.2, detail: '百草味 黄桃干100g*2 零食蜜饯水果干 杏果果脯杏脯', quantity: 1 }, { imgUrl: 'https://img.alicdn.com/bao/uploaded/i2/725677994/TB1Z1mzXMmTBuNjy1XbXXaMrVXa_!!0-item_pic.jpg_80x80.jpg', unitPrice: 19.90, weight: 0.15, detail: '百草味 黄桃干100g*2 零食蜜饯水果干 杏果果脯杏脯', quantity: 1 }, { imgUrl: 'https://img.alicdn.com/bao/uploaded/i2/725677994/TB1Z1mzXMmTBuNjy1XbXXaMrVXa_!!0-item_pic.jpg_80x80.jpg', unitPrice: 9.90, weight: 0.31, detail: '百草味 黄桃干100g*2 零食蜜饯水果干 杏果果脯杏脯', quantity: 1 } ] } var app = new Vue({ el: '#app', data: { goodTotal: 0, priceAll: 0, checkedAll: false, shopingcart: Data.test, checkedNames: [] }, methods: { add: function (index) { this.shopingcart[index].quantity++; console.log(this.shopingcart[index].quantity); // 如果checkedNames存在,即是选中 if (this.checkedNames.length > 0) { this.recalculation(this.checkedNames); } }, num: function (event, index) { if (event.target.value <= 0) { return false } var obj = event.target; this.shopingcart[index].quantity = event.target.value; // 如果checkedNames存在,即是选中 if (this.checkedNames.length > 0) { this.recalculation(this.checkedNames); } }, minus: function (index) { if (this.shopingcart[index].quantity <= 1) { return false } this.shopingcart[index].quantity--; // 如果checkedNames存在,即是选中 if (this.checkedNames.length > 0) { this.recalculation(this.checkedNames); } }, checkAll: function () { if (!this.checkAll) { this.checkAll = !this.checkAll; } }, recalculation: function (newVal) { var _this = this, Total = 0, priceAll = 0; // 获取总数total和合计元 newVal.forEach(function (item, index) { if (item == true) { Total += parseInt(_this.shopingcart[index].quantity); priceAll += _this.shopingcart[index].unitPrice * _this.shopingcart[index].quantity; } }) this.goodTotal = Total; this.priceAll = Math.ceil(parseFloat(priceAll) * 100) / 100; } }, watch: { checkedNames: function (newVal) { console.log(newVal) // 选项发生变化,重新计算价格 this.recalculation(newVal); }, checkedAll: function (Val) { var _this = this; if (!Val) { _this.checkedNames = [] return false; } // 先置为空,保证checkedNames发生变化 _this.checkedNames = [] this.shopingcart.forEach(function (item, index) { // _this.checkedNames[index] = true 此处有bug,为何? _this.checkedNames.push(true) }) } } }) /* * 受现代js的限制,vue不能检测到对象属性的添加或删除。 * 由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的 * */ </script> </body> </html>
闲来无事,使用非node环境的vue,写一些功能,vue主要是数据的变化,个人感觉是这样,第一次写微博,难免疏漏,请谅解。
本人试过直接,把checkbox的value和text的value直接绑定,数量为空时会有true和false出现,所以用checkedNames数组的形式控制多个input值,数据变化参考最下方span标签。
这里还有个坑就是受现代js的限制,vue不能检测到对象属性的添加或删除。
本例子没使用es6箭头函数,因此使用_this获取vue对象。
本例子通过监听checkedNames的变化,每次重新计算所有商品的数量变化,从而实现所有商品价格的计算,有些地方感觉有bug,但是没弄懂,希望大家一起探讨