今天根據(jù)京東購物車截圖,實(shí)現(xiàn)下面框出來的幾個(gè)簡單功能柱锹。
一、vue環(huán)境的搭建和項(xiàng)目新建
這里可以看我之前的文章vue環(huán)境搭建+項(xiàng)目新建
二丰包、大致思路
(1)根據(jù)上面的截圖禁熏,要寫一個(gè)循環(huán)列表,這里引用bootstrap中table樣式邑彪。然后把表格分為6列瞧毙,確認(rèn)好表頭:
(3)遍歷數(shù)據(jù)之前,先準(zhǔn)備好json文件寄症,里面寫好各個(gè)商品的信息宙彪,然后使用axios實(shí)現(xiàn)數(shù)據(jù)初始化,將獲取的數(shù)據(jù)賦值給products數(shù)組有巧。引用axios.js文件释漆。(關(guān)于axios的用法下面注釋中有詳細(xì)的介紹)
(2)從第二行開始,要通過v-for實(shí)現(xiàn)循環(huán)遍歷data數(shù)據(jù)篮迎,顯示每個(gè)商品的詳細(xì)信息男图,包括關(guān)于商品的操作部分示姿。
(3)最后逐步實(shí)現(xiàn)各塊的功能,最終結(jié)果如下圖所示:
三逊笆、功能實(shí)現(xiàn)
(1)商品數(shù)據(jù)信息格式
(2)初步實(shí)現(xiàn)
①這里的isSelected默認(rèn)都為true栈戳,直接在data中定義checkAll屬性為true,根據(jù)v-model雙向綁定獲取checkAll的值渲染在視圖上难裆。
②點(diǎn)擊全選框?qū)崿F(xiàn)全選和反選子檀,并根據(jù)每個(gè)復(fù)選框的狀態(tài)更新全選框的狀態(tài):
這里要特別注意:click點(diǎn)擊時(shí),checkbox的狀態(tài)還沒改變 乃戈,所以拿到的值總是相反的褂痰,遇到這種情況我們一般用change事件。change可以保證只當(dāng)值變化后再觸發(fā)函數(shù)症虑。
在全選框中添加@change="change"事件脐恩,在循環(huán)的復(fù)選框中添加@change="checkOne"事件。這里侦讨,同時(shí)在vue示例中定義兩個(gè)methods:change和checkOne,分別對應(yīng)實(shí)現(xiàn)上述的兩個(gè)小功能苟翻。
checkOne:使用every方法韵卤,只要遍歷到false就返回false,否則一直遍歷知道結(jié)束返回true崇猫,并賦給checkAll沈条;
change:通過forEach遍歷,實(shí)現(xiàn)對每個(gè)復(fù)選框的賦值诅炉。
③每件商品數(shù)量的設(shè)置:這里直接將input設(shè)為number類型蜡歹,并設(shè)置min=1,同時(shí)要在v-model后面加.number涕烧,v-model.number是為了保證在數(shù)據(jù)中的數(shù)值是number類型月而,因?yàn)椴患?number在后臺(tái)看見的數(shù)據(jù)是字符串的形式。
④針對屬性值的綁定议纯,例如:img的src父款、title、class瞻凤、style等憨攒,vue提供了v-bind的指令簡寫成:
⑤規(guī)范數(shù)據(jù)顯示:小計(jì)一欄,可以直接在{{}}中計(jì)算數(shù)量和單價(jià)的乘積獲取小計(jì)的值阀参,這種時(shí)候要對獲取的數(shù)據(jù)進(jìn)行規(guī)范化肝集。
這樣使用管道符的方法能夠很好的實(shí)現(xiàn)代碼toFixed()方法的復(fù)用,帶有保留即為的參數(shù)蛛壳,可以針對不同要求保留不同的小數(shù)位杏瞻,修改起來也很方便所刀。
⑥刪除:這個(gè)功能比較簡單,直接對每個(gè)button綁定remove方法伐憾,至于如何確定要?jiǎng)h的是哪一項(xiàng)勉痴,可以通過參數(shù)傳遞,將v-for獲得的product傳給remove树肃,然后使用filter方法對每一個(gè)item和product作比較蒸矛,如果相等則找到了要?jiǎng)h除的那項(xiàng),定義返回false胸嘴,不放進(jìn)新數(shù)組中雏掠,將其過濾掉,返回新的商品數(shù)組劣像。(廢話一堆乡话,其實(shí)看代碼就懂了^-^)
⑦總計(jì):每個(gè)商品數(shù)量和商品單價(jià)的乘積的累加求和,用reduce耳奕。
關(guān)于這些數(shù)組方法就不詳細(xì)描述了绑青,可參考JS數(shù)組方法集合
四、完善
這樣實(shí)現(xiàn)看似沒什么問題屋群,但是有兩點(diǎn):
(1)關(guān)于總計(jì)的值闸婴,sum寫在methods中,數(shù)據(jù)一變化就會(huì)重新調(diào)用此函數(shù)芍躏,算出新結(jié)果邪乍,它不會(huì)緩存上一次的結(jié)果,這樣的寫法性能不高对竣。
(2)關(guān)于全選的初值值庇楞,應(yīng)該要通過計(jì)算每個(gè)復(fù)選框的值得到的,而不是自己設(shè)的否纬,同樣如果添加計(jì)算方法吕晌,也會(huì)有(1)中提到的問題。
計(jì)算屬性
當(dāng)給全選賦值時(shí)要影響其他人的變化临燃,當(dāng)頁面刷新時(shí)我們獲取全選值是根據(jù)下面的checkbox來計(jì)算出來的結(jié)果給全選賦值聂使。相當(dāng)于get和set,可以使用computed谬俄,是一個(gè)計(jì)算屬性不是一個(gè)方法柏靶。
可以直接放在上面v-model中就可以實(shí)現(xiàn)數(shù)據(jù)-視圖的雙向綁定,就可以不用添加事件來改變數(shù)據(jù)視圖的結(jié)果即頁面刷新觸發(fā)get溃论,點(diǎn)擊復(fù)選框觸發(fā)set屎蜓。即:當(dāng)改變下面單個(gè)復(fù)選框時(shí)會(huì)觸發(fā)get更新全選的值;當(dāng)改變?nèi)x框時(shí)钥勋,設(shè)置全選框的值會(huì)觸發(fā)set重新對下面單個(gè)復(fù)選框進(jìn)行賦值炬转。(有點(diǎn)繞-.-)
根據(jù)這個(gè)思路可以對checkAll和sum改寫成computed形式辆苔。
computed:{
? ? checkAll:{
? ? ? ? get(){//get和set中this指向vm實(shí)例? 默認(rèn)v-model會(huì)獲取checkAll值觸發(fā)get方法
? ? ? ? ? ? return this.products.every(item=>item.isSelected);
? ? ? ? },
? ? ? ? //當(dāng)我們給checkbox賦值時(shí)會(huì)調(diào)用set方法
? ? ? ? set(val){
? ? ? ? ? ? ?this.products.forEach(item=>item.isSelected = val);
? ? ? ? },
? ? },
? ? sum:{//sum的結(jié)果會(huì)被緩存,如果以來的數(shù)據(jù)沒有變化就不會(huì)重新執(zhí)行
? ? ? ? get(){
? ? ? ? ? ? ? ? return this.products.reduce((prev,next)=>{
? ? ? ? ? ? ? ? ? ? ? ? if(! next.isSelected)return prev;? //如果當(dāng)前沒被選中扼劈,就不加當(dāng)前這一項(xiàng)
? ? ? ? ? ? ? ? ? ? ? ? return prev + next.productPrice*next.productCount;
? ? ? ? ? ? },0)
}
}
},
這里就可以省掉methods中的三個(gè)方法驻啤,直接將這些方法寫到computed計(jì)算屬性中,同時(shí)也不用定義data中的checkAll變量荐吵,代碼也更好管理骑冗。
最后簡單的購物車就實(shí)現(xiàn)啦,完整代碼參考vue-demo中的cart.html和computed-carts.html