vue实战,一步步实现vue购物车功能的过程记录,课程与素材来自慕课网,自己搭建了express本地服务器来请求数据
作者:狐狸家的鱼
本文链接:vue实战-实现购物车功能(五)
GitHub:sueRimn
一、单价商品的金额计算
整个操作过程是,商品的数量是可以控制的,可增可减,最少为1。并且在数量的变化中,商品的总价也在变化。
控制数量与总价的变化需要定义新方法。
页面中的+和-控制数量的变化,当点击的时候调用changeMoney()函数,传递参数,通过数量的变化去改变金额。+的时候增1,-的时候减1。
cart.html
<div class="quantity"> <!-- 商品数量 --> <a href="javascript:void 0" @click="changeMoney(item,-1)">-</a> <input type="text" value="0" disabled v-model="item.productQuantity"> <a href="javascript:void 0" @click="changeMoney(item,1)">+</a> </div>
cart.js
changeMoney: function (product,way) { if (way > 0){ product.productQuantity++; }else{ product.productQuantity--; if (product.productQuantity < 1) {//限制数量最少为1 product.productQuantity = 1; } } this.calcTotalPrice();//每次改变商品数量就调用计算总金额函数 },
二、单选选中商品
在购物车中,需要选择当前想买的商品,这一功能成为商品的单选,并且在选中商品的同时,总金额会累加上选中的商品总价。
需要绑定单选按钮的选中状态,选中为true,再次点击状态取反。
cart.html
<div class="cart-item-check"> <a href="javascript:void 0" class="item-check-btn" :class="{'check':item.checked}" @click="selectedProduct(item)"> <svg class="icon icon-ok"><use xlink:href="#icon-ok"></use></svg> </a> </div>
cart.js
新增方法:
selectedProduct: function (item) {//选中商品 if(typeof item.checked == 'undefined') {//检测属性是否存在 //Vue.set(item, "checked", true); this.$set(item, "checked", true);//局部注册 }else{ item.checked = !item.checked;//状态取反 } //如果取消一个商品的选中,全选也取消 var itemisChecked = []; this.productList.forEach(function (item, index){ if (item.checked === true ) { itemisChecked.push(item); } }) if (itemisChecked.length === this.productList.length ) { this.checkAllFlag = true; }else{ this.checkAllFlag = false; } //这个位置调用计算总金额的函数 },
这仅仅只是实现选中商品,如何进行选中商品的金额累加呢,需要进行金额的计算,新增方法:
calcTotalPrice: function () { this.totalMoney = 0;//每次遍历商品之前对总金额进行清零 this.productList.forEach((item, index) => {//遍历商品,如果选中就进行加个计算,然后累加 if (item.checked){ this.totalMoney += item.productPrice*item.productQuantity;//累加的 } }); },
然后在每一个需要对金额进行计算的地方都要调用这个函数。选中商品的最后就需要调用这个方法,所以在
this.calcTotalPrice();//选中商品后调用计算总金额函数
三、全选选中商品
全选就是一键选中所有商品,然后总金额是所有商品的总价的总和。取消全选有两个方式:一是直接按取消全选,而是取消任何一个商品的选中。
计算总金额的方法在上方已经提过,所以只需要在全选的方法后面调用该方法就可以计算所有的总金额。
全选和取消全选的方法就是各自传送一个状态flag,点击是谁就进行相关的操作,所以新增一个checkAll()方法。
先在data新增属性:
checkAllFlag: false,//选中全部
cart.html:
<div class="item-all-check"> <a href="javascript:void 0"> <span class="item-check-btn" :class="{'check':checkAllFlag}" @click="checkAll(true)"> <svg class="icon icon-ok"><use xlink:href="#icon-ok"></use></svg> </span> <span>全选</span> </a> </div> <div class="item-all-del"> <a href="javascript:void 0" class="item-del-btn" @click="checkAll(false)"> <span>取消全选</span> </a> </div>
cart.js
checkAll: function (flag) { this.checkAllFlag = flag; this.productList.forEach((item, index) => { if(typeof item.checked == 'undefined') {//检测属性是否存在 this.$set(item, "checked", this.checkAllFlag);//局部注册 }else{ item.checked = this.checkAllFlag;//状态取反 } }); this.calcTotalPrice();//全选时调用计算总金额函数 },
四、删除商品
点击每个商品后面的删除按钮,可以弹出一个确定是否删除该订单的模态框,点击no取消删除,点击Yes确定删除,确定删除后就会把当前商品从商品列表里删除。这一个操作本该是前台调用接口将当前元素的id传给后台进行删除操作,这里只是模拟删除数据。
这里存在一个问题还没解决,就是全选状态下删除某一个商品,总金额没有改变(待解决)
点击删除按钮时有一个状态传递,即点击那个商品后面的删除就把当前项传递给模态框的删除方法。
在data中新增属性:
delFlag:false,//删除 curProduct: ''//当前商品
cart.html
<a href="javascript:void 0" class="item-edit-btn" @click="delConfirm(item)"> <svg class="icon icon-del"><use xlink:href="#icon-del" ></use></svg> </a>
cart.js
delConfirm: function (item) { this.delFlag = true;//打开删除当前订单的模态框 this.curProduct = item;//确认点击的当前商品待删除 }, delProduct: function () {//这里只是模拟删除数据,真实的需要传递选中的商品元素的id传给后台,从后台删除 index = this.productList.indexOf(this.curProduct);//从当前商品列表找到要删除的商品元素 this.productList.splice(index, 1);//然后从列表里删除当前要删除的商品元素,数量为1 this.delFlag = false;//关闭模态框 }
cart.js的全部代码:
Vue.filter('money',(value,type) => {//全局过滤器 总价 return "¥ " + value.toFixed(2) + type;//保留两位小数 }); new Vue({ el:'#app', data: { totalMoney: 0,//总金额 productList: [],//商品列表 checkAllFlag: false,//选中全部 delFlag:false,//删除 curProduct: '' }, filters: {//局部过滤器 单价 formatMoney: function (value) { return "¥ " + value.toFixed(2);//保留两位小数 } }, mounted: function() {//挂载 钩子 实例插入文档 this.cartView(); }, methods: { cartView: function () { let _this = this; //获取数据,返回结果 this.$http.get("../data/cartData.json", {"id":123}).then(res => {//不必在外部声明 this this.productList = res.data.result.list; this.totalMoney = res.data.totalMoney; }); }, changeMoney: function (product,way) { if (way > 0){ product.productQuantity++; }else{ product.productQuantity--; if (product.productQuantity < 1) {//限制数量最少为1 product.productQuantity = 1; } } this.calcTotalPrice();//每次改变商品数量就调用计算总金额函数 }, selectedProduct: function (item) {//选中商品 if(typeof item.checked == 'undefined') {//检测属性是否存在 //Vue.set(item, "checked", true); this.$set(item, "checked", true);//局部注册 }else{ item.checked = !item.checked;//状态取反 } //如果取消一个商品的选中,全选也取消 var itemisChecked = []; this.productList.forEach(function (item, index){ if (item.checked === true ) { itemisChecked.push(item); } }) if (itemisChecked.length === this.productList.length ) { this.checkAllFlag = true; }else{ this.checkAllFlag = false; } this.calcTotalPrice();//选中商品后调用计算总金额函数 }, checkAll: function (flag) { this.checkAllFlag = flag; this.productList.forEach((item, index) => { if(typeof item.checked == 'undefined') {//检测属性是否存在 this.$set(item, "checked", this.checkAllFlag);//局部注册 }else{ item.checked = this.checkAllFlag;//状态取反 } }); this.calcTotalPrice();//全选时调用计算总金额函数 }, calcTotalPrice: function () { this.totalMoney = 0;//每次遍历商品之前对总金额进行清零 this.productList.forEach((item, index) => {//遍历商品,如果选中就进行加个计算,然后累加 if (item.checked){ this.totalMoney += item.productPrice*item.productQuantity;//累加的 } }); }, delConfirm: function (item) { this.delFlag = true;//打开删除当前订单的模态框 this.curProduct = item;//确认点击的当前商品待删除 }, delProduct: function () {//这里只是模拟删除数据,真实的需要传递选中的商品元素的id传给后台,从后台删除 index = this.productList.indexOf(this.curProduct);//从当前商品列表找到要删除的商品元素 this.productList.splice(index, 1);//然后从列表里删除当前要删除的商品元素,数量为1 this.delFlag = false;//关闭模态框 } }, });