使用Vue做一個購物車

cy不想說話發表於2019-03-03

本人最近在個人部落格寫一個小型的Vue實戰文章,努力中,歡迎各位前往檢視,指導點評!地址:Cy的個人部落格

前言

最近我實習的公司在做網上商城的一個專案,我負責購物車這一塊。這個專案是一個Web專案,沒有進行前後端分離,但是又得做手機端,感覺好像哪裡不對。。。 web框架使用的是SpringMVC,模板框架是FreeMarker,想到以後要做移動端,果斷還是用json來進行資料互動,並沒有用freemarker。網頁靜態檔案全部寫好了,放在了springmvc的Views中。按理來說還是進行前後端分離好點的,但是做網頁的沒接觸過Vue,那好吧。。。 於是我就想到在頁面直接引入Vue,可是又是在內網環境開發,只好在自己個人筆記本上下載vue.js再拷貝到內網電腦上進行頁面上的引入。

正文

首先讓我們看一下靜態頁面的效果圖:

靜態頁面效果圖

簡單說一下這個功能模組的需求:
  1. 勾選全選,所有商品全部選中。在取消全選框的時候所有商品取消選擇。
  2. 點選單個商品上的加號減號進行數量的增加和減少,右邊小計實時計算出這個商品的價格合計。
  3. 點選單個商品上的刪除按鈕將商品從購物車中刪除。
  4. 底部已選實時顯示已經勾選的商品,右邊合計金額實時顯示所有勾選的商品的小計之和。 (是的,需求看起來不多,但是要結合後臺去做還是需要點功夫的,但是這篇文章我們不牽扯後臺,在前臺造資料)
現在讓我們開始吧

,建立一個Vue物件,設定好資料。

var cart; //全域性Vue物件
//通過封裝一個方法來建立Vue物件
function createVue(list) {  //傳入通過後臺獲取的list
  cart = new Vue({
	el:'#cart',
	data(){
		return {
			list:list  //商品列表
		}
	}
  });
}
複製程式碼

,假設從後臺請求到資料,然後賦值到Vue物件中

window.onload = function () {
		//請求後臺程式碼   。。。。
		//請求成功後將獲得的list賦值給cart的list
		let list = [
			{
				goodsTitle: "衛龍辣條",						    //商品名
				specifications: "大包",						 //商品規格
				unitPrice: "5",								  //商品單價
				subimage1Filename :"20180317eeftyd.jpg",		//商品圖片名
				purchaseQuantity: 6						//商品數量
			}, 
			{
				goodsTitle: "雕牌洗衣粉",
				specifications: "大包",
				unitPrice: "13",
				subimage1Filename: "20180317ggptfg.jpg",
				purchaseQuantity: 1
			}, 
			{
				goodsTitle: "旺仔牛奶",
				specifications: "20盒裝",
				unitPrice: "45",
				subimage1Filename: "20180317feftyp.jpg",
				purchaseQuantity: 1
			}];
			createVue(list);  //執行建立Vue物件方法
	}
);
複製程式碼

,修改html部分程式碼,將資料展示出來

<tr v-for="(item,index) in list">
  <td>
	<input type="checkbox" :id="'check'+index" name="checkboxs" />
	<label :for="'check'+index"></label>
  </td>
  <td>
	<img :src="'路徑字首/'+item.subimage1Filename" />
  </td>
  <td style="text-align:left;">
	<p>{{item.goodsTitle}}</p>
	<p>規格:{{item.specifications}}</p>
  </td>
  <td>¥{{item.unitPrice}}</td>
  <td class="adddel">
	<em v-on:click="minius(index)">-</em>
	<input type="number" v-model.number="item.purchaseQuantity" />
	<em v-on:click="add(index)">+</em>
  </td>
  <td>¥{{item.unitPrice * item.purchaseQuantity}}</td>
  <td><button v-on:click="checkDel(index)">刪除</button></td>
</tr> 
複製程式碼

這樣就能將單個商品部分全部迴圈列印出來,並且將對應的資訊列印在對應位置。效果圖如下:

效果圖,圖中的圖片名和路徑是我編的,所以找不到
,實現全選和勾選時候總價的計算,這部分算是有點挑戰了。我的思路是在Vue物件中新增加一個資料用來標識商品的選中狀態,所以建立Vue方法中的程式碼改成如下所示:

cart = new Vue({
	el: '#cart',
		data() {
			return {
				list: list,
				checkeds: new Array(list.length) //初始化成list的長度
		}
	});
複製程式碼

然後在html中將商品對應的checkbox與checkeds繫結起來,修改後的程式碼如下:

<input type="checkbox" :id="'check'+index" name="checkboxs" v-model="checkeds[index]" />
複製程式碼

利用computed屬性計算價格總和:

sum () {
	let sum = 0;
	for (let i in this.list) {
		if (this.checkeds[i])  //如果checkeds[i]的結果為truth,則進行累加
		  sum += this.list[i].unitPrice * this.list[i].purchaseQuantity;
	}
	return sum;
}
複製程式碼

HTML部分,我們在對應位置用{{sum}}帶入就能進行顯示了。這樣就能實現計算勾選過的商品小計之和了。接下來實現全選功能,在methods屬性中新增一個方法checkAll,具體程式碼如下:

checkAll (event) {  //這裡的event就是全選checkbox物件
	if (event.checked) {  //如果全選的checkbox選中,將checkeds所有的值設定為true,對應商品checkbox的選中狀態自動更新
		for (let i = 0; i < this.checkeds.length; i++) {
			Vue.set(this.checkeds, i, true);
		}
	 else {  //否則就進行與上面相反的操作
		for (let i = 0; i < this.checkeds.length; i++) {
			Vue.set(this.checkeds, i, false);
		}
	}
}
複製程式碼

經過上面的一波操作,已經可以實現全選和點選時候的價格之和計算。我們還要統計商品選中的數量,這個很簡單,同樣使用computed屬性,對checkeds中結果為truth的進行統計就好了,程式碼如下:

checkNum: function () {
	let num = 0;
	for (let i in this.checkeds) {
		if (this.checkeds[i]) {
			num++;
		}
	}
	return num;
}
複製程式碼

然後在html中的對應位置用{{checkNum}}代入即可。現在我們已經實現了近一半需求,讓我們繼續完成他們吧! ,實現購物車物品單個刪除功能,這個就很簡單啦,我們在methods中增加一個del方法,使用js陣列的splice方法就可以實現。

del (index) {
    this.list.splice(index, 1);  //只需要從陣列中移除對應項,檢視會自動更新,不得不說,Vue太棒啦!
    this.checkeds.splice(index,1); //同時刪除對應的選中狀態標識
}
複製程式碼

然後就是給刪除按鈕繫結點選事件(index是迴圈列表時候的下標):

<button v-on:click="del(index)">刪除</button>
複製程式碼

這樣我們就輕鬆實現了刪除單個商品的需求,當然防止使用者誤刪,在使用者點選刪除按鈕時我們可以彈出一個確認框提示使用者,這裡我們就不去實現了。 ,實現購物車單個商品的數量增加,減少,並實時更新商品的小計。首先在methods中新增增加方法add和減少方法minius:

add (index) {
	this.list[index].purchaseQuantity++;  //這裡按理來說應該查詢後臺對應商品庫存量來進行限制的,這裡不涉及到後臺所以沒加
},
minius (index) {
	if (this.list[index].purchaseQuantity > 1) {  //這裡新增一個限制,最少要有一個商品
		this.list[index].purchaseQuantity--;
	}
}
複製程式碼

然後我們在對應的加和減的按鈕上繫結事件來觸發這兩個方法(index為列表迴圈時候的下標):

<td class="adddel">
	<em v-on:click="minius(index)">-</em>
	<input type="number" v-model.number="item.purchaseQuantity" />
	<em v-on:click="add(index)">+</em>
</td>
<td>¥{{item.unitPrice * item.purchaseQuantity}}</td>
複製程式碼

從上面的程式碼可以看到我們在小計一欄直接進行商品單價和數量相乘,這樣就可以實現實時更新了。

至此,我們的需求就算是完成了,最後給大家留兩個小問題思考一下

,如何實現批量刪除? ,在全選之後,我們取消了一個商品的狀態,全選框的選中狀態仍然是選中的,此時應該是不選中的,或者當我們一個一個把商品的選中狀態全部勾選,全選框的狀態仍然是補選中的,此時應該是選中狀態(如下兩圖所示),這個現象如何解決?

問題二的現象一
問題二的現象二

後文

本文的所有程式碼已經託管到GitHub,如果本文程式碼有誤,請以GitHub上的為準,GitHub地址:github.com/cyixlq/vue_…

相關文章