最近我實習的公司在作網上商城的一個項目,我負責購物車這一塊。這個項目是一個Web項目,沒有進行先後端分離,可是又得作手機端,感受好像哪裏不對。。。 web框架使用的是SpringMVC,模板框架是FreeMarker,想到之後要作移動端,果斷仍是用json來進行數據交互,並無用freemarker。網頁靜態文件所有寫好了,放在了springmvc的Views中。按理來講仍是進行先後端分離好點的,可是作網頁的沒接觸過Vue,那好吧。。。 因而我就想到在頁面直接引入Vue,但是又是在內網環境開發,只好在本身我的筆記本上下載vue.js再拷貝到內網電腦上進行頁面上的引入。html
首先讓咱們看一下靜態頁面的效果圖:vue
一,建立一個Vue對象,設置好數據。git
var cart; //全局Vue對象
//經過封裝一個方法來建立Vue對象
function createVue(list) { //傳入經過後臺獲取的list
cart = new Vue({
el:'#cart',
data(){
return {
list:list //商品列表
}
}
});
}
複製代碼
二,假設從後臺請求到數據,而後賦值到Vue對象中github
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部分代碼,將數據展現出來web
<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>
複製代碼
這樣就能將單個商品部分所有循環打印出來,而且將對應的信息打印在對應位置。效果圖以下:spring
四,實現全選和勾選時候總價的計算,這部分算是有點挑戰了。個人思路是在Vue對象中新增長一個數據用來標識商品的選中狀態,因此建立Vue方法中的代碼改爲以下所示:cart = new Vue({
el: '#cart',
data() {
return {
list: list,
checkeds: new Array(list.length) //初始化成list的長度
}
});
複製代碼
而後在html中將商品對應的checkbox與checkeds綁定起來,修改後的代碼以下:json
<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的進行統計就行了,代碼以下:bash
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_…