vue實戰,一步步實現vue購物車功能的過程記錄,課程與素材來自慕課網,本身搭建了express本地服務器來請求數據javascript
做者:狐狸家的魚html
本文連接:vue實戰-實現購物車功能(五)vue
GitHub:sueRimnjava
整個操做過程是,商品的數量是能夠控制的,可增可減,最少爲1。而且在數量的變化中,商品的總價也在變化。git
控制數量與總價的變化須要定義新方法。github
頁面中的+和-控制數量的變化,當點擊的時候調用changeMoney()函數,傳遞參數,經過數量的變化去改變金額。+的時候增1,-的時候減1。express
cart.htmljson
<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();//每次改變商品數量就調用計算總金額函數 },
在購物車中,須要選擇當前想買的商品,這一功能成爲商品的單選,而且在選中商品的同時,總金額會累加上選中的商品總價。app
須要綁定單選按鈕的選中狀態,選中爲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;//關閉模態框 } }, });