上篇完成了商品從詳情頁添加到購物車界面的邏輯归露,現(xiàn)在在購物車界面已經可以拿到購物車里的商品列表,現(xiàn)在要處理在購物車界面的一些邏輯苟耻。
功能拆分
購物車界面還是有些東西的吱瘩,涉及到多處數據的同步更改荷逞,下面對功能進行拆分:
- 商品選擇和取消選擇
- 總金額計算
- 全選
經過上篇操作現(xiàn)在在購物車界面已經可以拿到要添加到購物車頁面的商品列表媒咳。單個商品的數據結構如下:
{
image: "https://i.loli.net/2020/04/19/m1v4HcARnMsadUq.jpg",
title: "2060款手機傻妞為你服務",
desc: "十年老店",
price: "29.98",
iid: "cemcoe",
count: 4
}
有了這些數據就可以進行渲染展示了。上篇已進行編碼种远,這里不再重復涩澡。
商品是否選中
第一個功能點是商品的選中和不選中。
先是視覺上的選中和取消選中坠敷。
明顯是切換妙同,這樣的場景在 Vue 組件 | 如何從零封裝一個tabbar組件 時有遇到,選中時紅色圖標膝迎,沒選中時灰色圖標粥帚。當時是準備了兩組圖片,當用戶點擊時切換圖片資源限次。這里也可以使用上述方案芒涡。
但有沒有更好的方式?
這里的選擇按鈕并不復雜卖漫,其實改變個背景色就好了费尽。
這里用到動態(tài)綁定 class 的方案,當選中時給個紅色的背景羊始,沒選中時給個灰色背景旱幼。重點是定義一個變量決定是否給元素添加對應的類名。
上面就是視覺上的邏輯實現(xiàn)突委。
下面是功能上的柏卤,首先要知道商品當前的狀態(tài),即是否被選中匀油?當商品對應的按鈕被選中時缘缚,要放到商品結算列表,用于最后總金額的計算钧唐。
上面的商品對象并沒有我們需要的變量忙灼,不妨暫定 checked 并到 Vuex 中定義匠襟。
// mutations.js
export default {
// mutations 唯一目的是修改state中狀態(tài)
// mutations 每個方法盡可能完成單一事件
[ADD_COUNTER](state, payload) {
payload.count++
},
[ADD_TO_CART](state, payload) {
payload.checked = true
state.cartList.push(payload)
}
}
這個 checked 默認是 true钝侠,即用戶在詳情頁將商品添加到購物車時商品默認是選中的狀態(tài)该园。
有了 checked 這個值我們就可以來判斷商品按鈕的狀態(tài)了。對按鈕進行事件監(jiān)聽帅韧,并在用戶點擊時更改按鈕的狀態(tài)里初。
methods: {
checkClick() {
this.itemInfo.checked = !this.itemInfo.checked
console.log("改變商品選擇狀態(tài)成功")
}
}
在 Vuex 中定義了 checked 屬性后,此時一個商品對象的數據類型變成了這樣:
{
image: "https://i.loli.net/2020/04/19/m1v4HcARnMsadUq.jpg",
title: "2060款手機傻妞為你服務",
desc: "十年老店",
price: "29.98",
iid: "cemcoe",
count: 4,
checked: true
}
總金額的計算
底部的功能欄是三欄布局忽舟,布局樣式這里就不寫了双妨,flex 一把梭。
那么此時的問題就變成了一道數學題叮阅。
如何計算總金額刁品?
總金額 = 選中的商品 * 數量 * 單價
現(xiàn)在的問題是找到這些變量,看一下商品對象的數據類型不難找到浩姥。
checked: 是否選中
count: 數量
price: 單價
問題轉變成了對象數組的求和問題挑随,先找到 cartList 中 checked 值為 true 的商品對象,然后找到這些對象的 count 和 price勒叠,將這些變量套到公式里兜挨。
totalPrice() {
return (
"¥" +
this.$store.state.cartList
.filter(item => {
return item.checked
})
.reduce((preValue, item) => {
return preValue + item.price * item.count
}, 0)
)
}
上面用到了數組的兩個高階函數,filter 用于過濾數組中符合條件的元素眯分,reduce 用于將數組中的元素進行匯總成一個值拌汇。
全選
在該頁面有兩種對號,一種是商品前面弊决,一種就是底部的全選噪舀。
全選的邏輯是當商品全部被選中時,全選是紅色丢氢,否則是灰色傅联。
點擊全選,商品要么全變紅疚察,要么全變灰色蒸走。
computed:{
checkLength() {
return this.$store.state.cartList.filter(item => {
return item.checked
}).length
},
isSelectAll() {
// 全選狀態(tài)
if (this.$store.state.cartList.length === 0) return false
return !this.$store.state.cartList.find(item => !item.checked)
}
}
methods: {
checkClick() {
if (this.isSelectAll) {
// 全部選中
console.log("已全選")
this.$store.state.cartList.forEach(item => (item.checked = false))
} else {
// 有部分未選擇
console.log("有部分未選中")
this.$store.state.cartList.forEach(item => (item.checked = true))
}
}
}
先來兩個計算屬性,checkLength 被選中商品的數量貌嫡,isSelectAll 是否處于全選的狀態(tài)比驻。計算屬性用來控制全選按鈕的狀態(tài)。
而后是功能代碼 checkClick岛抄,用來響應用戶的點擊别惦,當處于全選狀態(tài)點擊時,要將每個商品對象的 checked 屬性改成 false夫椭。如果有部分未選中點擊時掸掸,將全部的商品對象的checked 屬性改成 true。
checkClick 通過改變商品的 checked 屬性影響 checkLength,進而影響 isSelectAll扰付,最總影響按鈕的展示堤撵。
購物車完。