Vue實現(xiàn)淘寶購物車三級選中功能詳解
最近在練習商城項目,記錄下實現(xiàn)購物車三級選中的過程(小白一個,水平很菜)
效果圖:
實現(xiàn):
1.全選時所有商品+店鋪全部選中;反之全部取消選中
2.店鋪選中時,當前店鋪內(nèi)所有商品選中;反之取消選中
3.店鋪內(nèi)商品全選 → 所屬店鋪選中;反之取消選中店鋪
4.店鋪+所有商品全選 → 全選按鈕選中;反之取消選中
首先說明一下,我使用了vuex來管理購物車數(shù)據(jù),所有改變按鈕狀態(tài)的方法都寫在mutaition里
const state = { cartList: [], // 購物車列表 totalCount: 0, allChecked: false, // 全選 shopCheckedNum: 0, // 選中的店鋪數(shù)量 /** * cartList: [ * { * shopName, * shopChecked: false, // 店鋪選中 * proCheckedNum: 0, // 當前店鋪商品選中數(shù)量 * cartGoodsInfo: [ * {iid,styleName,proChecked...} // 里邊是商品的各種信息,proChecked是商品選中狀態(tài) * {...} * ] * }, * {...} * ] */ };
html選擇按鈕部分
// 這是選擇按鈕,我把它封裝成了一個組件 chooseClass接收父組件傳值改變選中時的樣式 // 商品的選中按鈕 <cart-choose :chooseClass="$store.state.cartList[index].products[key].proChecked" @click.native.stop="proCheckedClick(index, key)" /> // 店鋪的選擇按鈕 (我把店鋪列表和商品分成了兩個組件,index是傳給店鋪列表內(nèi)商品的) <cart-choose :index="index" :chooseClass="$store.state.cartList[index].shopChecked" @click.native="shopCheckedClick(index)" /> // 全選按鈕 <cart-choose :chooseClass="$store.state.allChecked" />
商品,店鋪,全選按鈕的點擊方法
// index:店鋪索引值 key:當前商品在當前店鋪內(nèi)的索引值 proCheckedClick(index, key) { this.$store.dispatch("ProChecked", { index, key }); }, shopCheckedClick(index) { this.$store.dispatch("ShopChecked", index); }, allChecked() { this.$store.dispatch("AllChecked"); },
mutations
// 單個商品選中 proCheckedTrue(state, { index, key }) { const cartList = state.cartList; cartList[index].products[key].proChecked = true; cartList[index].proCheckedNum += 1; // 商品數(shù)量+1 }, // 單個商品取消選中 proCheckedFalse(state, { index, key }) { const cartList = state.cartList; cartList[index].products[key].proChecked = false; cartList[index].proCheckedNum -= 1; }, // 店鋪選中 shopCheckedTrue(state, index) { const cartList = state.cartList; cartList[index].shopChecked = true; console.log(state.shopCheckedNum); state.shopCheckedNum += 1; // 店鋪數(shù)量+1 }, // 店鋪取消選中 shopCheckedFalse(state, index) { const cartList = state.cartList; cartList[index].shopChecked = false; state.shopCheckedNum -= 1; }, // 全選 allCheckedTrue(state) { state.allChecked = true; }, // 取消全選 allCheckedFalse(state) { state.allChecked = false; },
因為方法涉及到一些邏輯判斷,我把邏輯判斷的部分都放在了actions里
// 商品狀態(tài) ProChecked({ state, commit }, { index, key }) { const cartList = state.cartList; // 這里要取反,因為此時的proChecked是點擊按鈕前的 !cartList[index].products[key].proChecked ? commit("proCheckedTrue", { index, key }) : commit("proCheckedFalse", { index, key }); // 商品全選,所選店鋪選中 if (cartList[index].proCheckedNum === cartList[index].products.length) { commit("shopCheckedTrue", index); } // 商品沒全選 → 如果店鋪選中改為未選中 // (不加這個判斷條件的話 本來沒選中的店鋪也會執(zhí)行shopCheckedFalse,導致商品選中數(shù)量會-1) else if (cartList[index].shopChecked) { commit("shopCheckedFalse", index); } // 判斷店鋪是否全選,改變?nèi)x按鈕狀態(tài) if (state.shopCheckedNum === cartList.length) { commit("allCheckedTrue"); } else { commit("allCheckedFalse"); } }, // 店鋪選中狀態(tài) ShopChecked({ state, commit }, index) { const cartList = state.cartList; if (!cartList[index].shopChecked) { // 讓店鋪選中 → 將當前店鋪內(nèi)未選中的商品改為選中 commit("shopCheckedTrue", index); for (let k in cartList[index].products) { if (!cartList[index].products[k].proChecked) { commit("proCheckedTrue", { index, key: k }); } } } else { // 店鋪取消選中 → 將當前店鋪內(nèi)所有商品改為未選中 commit("shopCheckedFalse", index); for (let k in cartList[index].products) { commit("proCheckedFalse", { index, key: k }); } } if (state.shopCheckedNum === cartList.length) { commit("allCheckedTrue"); } else { commit("allCheckedFalse"); } }, // 全選 AllChecked({ state, commit }) { const cartList = state.cartList; if (!state.allChecked) { // 全選 → 所有未選中的店鋪+商品全部選中 commit("allCheckedTrue"); for (let i in cartList) { if (!cartList[i].shopChecked) { commit("shopCheckedTrue", i); } for (let k in cartList[i].products) { if (!cartList[i].products[k].proChecked) { commit("proCheckedTrue", { index: i, key: k }); } } } } else { // 取消全選 → 所有店鋪+商品取消選中 commit("allCheckedFalse"); for (let i in cartList) { commit("shopCheckedFalse", i); for (let k in cartList[i].products) { commit("proCheckedFalse", { index: i, key: k }); } } } },
最開始我是把這些代碼都放在了三個方法里,這樣寫也能實現(xiàn),但是看起來實在太亂了,而且不能追蹤到具體是進行了什么操作。不想搞那么多方法的可以看看
// 單個商品選中 ProChecked(state, { index, key }) { const cartList = state.cartList; // 商品選中狀態(tài)取反 cartList[index].products[key].proChecked = !cartList[index].products[key].proChecked; // 如果選中,選中數(shù)量+1,取消選中則-1 if (cartList[index].products[key].proChecked) { cartList[index].proCheckedNum++; } else { cartList[index].proCheckedNum--; } // 如果商品全選,則店鋪選中;否則店鋪取消選中 if (cartList[index].proCheckedNum === cartList[index].products.length) { cartList[index].shopChecked = true; state.shopCheckedNum++; } else if (cartList[index].shopChecked) { cartList[index].shopChecked = false; state.shopCheckedNum--; } // 判斷店鋪是否全選,改變?nèi)x按鈕狀態(tài) if (state.shopCheckedNum === cartList.length) { state.allChecked = true;
到此這篇關(guān)于Vue實現(xiàn)淘寶購物車三級選中功能詳解的文章就介紹到這了,更多相關(guān)Vue購物車三級選中功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue獲取token實現(xiàn)token登錄的示例代碼
最近新做了個vue項目,正好項目中有登錄部分,本文就詳細的介紹一下登錄部分的實現(xiàn),文中通過示例代碼介紹的非常詳細,感興趣的小伙伴們可以參考一下2021-11-11vue draggable resizable gorkys與v-chart使用與總結(jié)
這篇文章主要介紹了vue draggable resizable gorkys與v-chart使用與總結(jié),本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09Vue??vuex配置項和多組件數(shù)據(jù)共享案例分享
這篇文章主要介紹了Vue??vuex配置項和多組件數(shù)據(jù)共享案例分享,文章圍繞Vue?Vuex的相關(guān)資料展開配置項和多組件數(shù)據(jù)共享的案例分享,需要的小伙伴可以參考一下2022-04-04VUE-Table上綁定Input通過render實現(xiàn)雙向綁定數(shù)據(jù)的示例
今天小編就為大家分享一篇VUE-Table上綁定Input通過render實現(xiàn)雙向綁定數(shù)據(jù)的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08