今天根據(jù)京東購物車截圖,實現(xiàn)下面框出來的幾個簡單功能。

一、vue環(huán)境的搭建和項目新建
這里可以看我之前的文章vue環(huán)境搭建+項目新建
二、大致思路
(1)根據(jù)上面的截圖,要寫一個循環(huán)列表,這里引用bootstrap中table樣式。然后把表格分為6列,確認好表頭:

(3)遍歷數(shù)據(jù)之前,先準備好json文件,里面寫好各個商品的信息,然后使用axios實現(xiàn)數(shù)據(jù)初始化,將獲取的數(shù)據(jù)賦值給products數(shù)組。引用axios.js文件。(關(guān)于axios的用法下面注釋中有詳細的介紹)

(2)從第二行開始,要通過v-for實現(xiàn)循環(huán)遍歷data數(shù)據(jù),顯示每個商品的詳細信息,包括關(guān)于商品的操作部分。

(3)最后逐步實現(xiàn)各塊的功能,最終結(jié)果如下圖所示:

三、功能實現(xiàn)
(1)商品數(shù)據(jù)信息格式

(2)初步實現(xiàn)
①這里的isSelected默認都為true,直接在data中定義checkAll屬性為true,根據(jù)v-model雙向綁定獲取checkAll的值渲染在視圖上。
②點擊全選框?qū)崿F(xiàn)全選和反選,并根據(jù)每個復(fù)選框的狀態(tài)更新全選框的狀態(tài):
這里要特別注意:click點擊時,checkbox的狀態(tài)還沒改變 ,所以拿到的值總是相反的,遇到這種情況我們一般用change事件。change可以保證只當值變化后再觸發(fā)函數(shù)。
在全選框中添加@change="change"事件,在循環(huán)的復(fù)選框中添加@change="checkOne"事件。這里,同時在vue示例中定義兩個methods:change和checkOne,分別對應(yīng)實現(xiàn)上述的兩個小功能。

checkOne:使用every方法,只要遍歷到false就返回false,否則一直遍歷知道結(jié)束返回true,并賦給checkAll;
change:通過forEach遍歷,實現(xiàn)對每個復(fù)選框的賦值。
③每件商品數(shù)量的設(shè)置:這里直接將input設(shè)為number類型,并設(shè)置min=1,同時要在v-model后面加.number,v-model.number是為了保證在數(shù)據(jù)中的數(shù)值是number類型,因為不加.number在后臺看見的數(shù)據(jù)是字符串的形式。
④針對屬性值的綁定,例如:img的src、title、class、style等,vue提供了v-bind的指令簡寫成:

⑤規(guī)范數(shù)據(jù)顯示:小計一欄,可以直接在{{}}中計算數(shù)量和單價的乘積獲取小計的值,這種時候要對獲取的數(shù)據(jù)進行規(guī)范化。

這樣使用管道符的方法能夠很好的實現(xiàn)代碼toFixed()方法的復(fù)用,帶有保留即為的參數(shù),可以針對不同要求保留不同的小數(shù)位,修改起來也很方便。

⑥刪除:這個功能比較簡單,直接對每個button綁定remove方法,至于如何確定要刪的是哪一項,可以通過參數(shù)傳遞,將v-for獲得的product傳給remove,然后使用filter方法對每一個item和product作比較,如果相等則找到了要刪除的那項,定義返回false,不放進新數(shù)組中,將其過濾掉,返回新的商品數(shù)組。(廢話一堆,其實看代碼就懂了^-^)

⑦總計:每個商品數(shù)量和商品單價的乘積的累加求和,用reduce。

關(guān)于這些數(shù)組方法就不詳細描述了,可參考JS數(shù)組方法集合
四、完善
這樣實現(xiàn)看似沒什么問題,但是有兩點:
(1)關(guān)于總計的值,sum寫在methods中,數(shù)據(jù)一變化就會重新調(diào)用此函數(shù),算出新結(jié)果,它不會緩存上一次的結(jié)果,這樣的寫法性能不高。
(2)關(guān)于全選的初值值,應(yīng)該要通過計算每個復(fù)選框的值得到的,而不是自己設(shè)的,同樣如果添加計算方法,也會有(1)中提到的問題。
計算屬性
當給全選賦值時要影響其他人的變化,當頁面刷新時我們獲取全選值是根據(jù)下面的checkbox來計算出來的結(jié)果給全選賦值。相當于get和set,可以使用computed,是一個計算屬性不是一個方法。
可以直接放在上面v-model中就可以實現(xiàn)數(shù)據(jù)-視圖的雙向綁定,就可以不用添加事件來改變數(shù)據(jù)視圖的結(jié)果即頁面刷新觸發(fā)get,點擊復(fù)選框觸發(fā)set。即:當改變下面單個復(fù)選框時會觸發(fā)get更新全選的值;當改變?nèi)x框時,設(shè)置全選框的值會觸發(fā)set重新對下面單個復(fù)選框進行賦值。(有點繞-.-)
根據(jù)這個思路可以對checkAll和sum改寫成computed形式。
computed:{
? ? checkAll:{
? ? ? ? get(){//get和set中this指向vm實例? 默認v-model會獲取checkAll值觸發(fā)get方法
? ? ? ? ? ? return this.products.every(item=>item.isSelected);
? ? ? ? },
? ? ? ? //當我們給checkbox賦值時會調(diào)用set方法
? ? ? ? set(val){
? ? ? ? ? ? ?this.products.forEach(item=>item.isSelected = val);
? ? ? ? },
? ? },
? ? sum:{//sum的結(jié)果會被緩存,如果以來的數(shù)據(jù)沒有變化就不會重新執(zhí)行
? ? ? ? get(){
? ? ? ? ? ? ? ? return this.products.reduce((prev,next)=>{
? ? ? ? ? ? ? ? ? ? ? ? if(! next.isSelected)return prev;? //如果當前沒被選中,就不加當前這一項
? ? ? ? ? ? ? ? ? ? ? ? return prev + next.productPrice*next.productCount;
? ? ? ? ? ? },0)
}
}
},
這里就可以省掉methods中的三個方法,直接將這些方法寫到computed計算屬性中,同時也不用定義data中的checkAll變量,代碼也更好管理。
最后簡單的購物車就實現(xiàn)啦,完整代碼參考vue-demo中的cart.html和computed-carts.html