Vue實(shí)現(xiàn)淘寶購物車三級選中功能詳解
最近在練習(xí)商城項(xiàng)目,記錄下實(shí)現(xiàn)購物車三級選中的過程(小白一個(gè),水平很菜)
效果圖:
實(shí)現(xiàn):
1.全選時(shí)所有商品+店鋪全部選中;反之全部取消選中
2.店鋪選中時(shí),當(dāng)前店鋪內(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, // 當(dāng)前店鋪商品選中數(shù)量 * cartGoodsInfo: [ * {iid,styleName,proChecked...} // 里邊是商品的各種信息,proChecked是商品選中狀態(tài) * {...} * ] * }, * {...} * ] */ };
html選擇按鈕部分
// 這是選擇按鈕,我把它封裝成了一個(gè)組件 chooseClass接收父組件傳值改變選中時(shí)的樣式 // 商品的選中按鈕 <cart-choose :chooseClass="$store.state.cartList[index].products[key].proChecked" @click.native.stop="proCheckedClick(index, key)" /> // 店鋪的選擇按鈕 (我把店鋪列表和商品分成了兩個(gè)組件,index是傳給店鋪列表內(nèi)商品的) <cart-choose :index="index" :chooseClass="$store.state.cartList[index].shopChecked" @click.native="shopCheckedClick(index)" /> // 全選按鈕 <cart-choose :chooseClass="$store.state.allChecked" />
商品,店鋪,全選按鈕的點(diǎn)擊方法
// index:店鋪索引值 key:當(dāng)前商品在當(dāng)前店鋪內(nèi)的索引值 proCheckedClick(index, key) { this.$store.dispatch("ProChecked", { index, key }); }, shopCheckedClick(index) { this.$store.dispatch("ShopChecked", index); }, allChecked() { this.$store.dispatch("AllChecked"); },
mutations
// 單個(gè)商品選中 proCheckedTrue(state, { index, key }) { const cartList = state.cartList; cartList[index].products[key].proChecked = true; cartList[index].proCheckedNum += 1; // 商品數(shù)量+1 }, // 單個(gè)商品取消選中 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; },
因?yàn)榉椒ㄉ婕暗揭恍┻壿嬇袛啵野堰壿嬇袛嗟牟糠侄挤旁诹薬ctions里
// 商品狀態(tài) ProChecked({ state, commit }, { index, key }) { const cartList = state.cartList; // 這里要取反,因?yàn)榇藭r(shí)的proChecked是點(diǎn)擊按鈕前的 !cartList[index].products[key].proChecked ? commit("proCheckedTrue", { index, key }) : commit("proCheckedFalse", { index, key }); // 商品全選,所選店鋪選中 if (cartList[index].proCheckedNum === cartList[index].products.length) { commit("shopCheckedTrue", index); } // 商品沒全選 → 如果店鋪選中改為未選中 // (不加這個(gè)判斷條件的話 本來沒選中的店鋪也會執(zhí)行shopCheckedFalse,導(dǎo)致商品選中數(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) { // 讓店鋪選中 → 將當(dāng)前店鋪內(nèi)未選中的商品改為選中 commit("shopCheckedTrue", index); for (let k in cartList[index].products) { if (!cartList[index].products[k].proChecked) { commit("proCheckedTrue", { index, key: k }); } } } else { // 店鋪取消選中 → 將當(dāng)前店鋪內(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 }); } } } },
最開始我是把這些代碼都放在了三個(gè)方法里,這樣寫也能實(shí)現(xiàn),但是看起來實(shí)在太亂了,而且不能追蹤到具體是進(jìn)行了什么操作。不想搞那么多方法的可以看看
// 單個(gè)商品選中 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實(shí)現(xiàn)淘寶購物車三級選中功能詳解的文章就介紹到這了,更多相關(guān)Vue購物車三級選中功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue獲取token實(shí)現(xiàn)token登錄的示例代碼
最近新做了個(gè)vue項(xiàng)目,正好項(xiàng)目中有登錄部分,本文就詳細(xì)的介紹一下登錄部分的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),感興趣的小伙伴們可以參考一下2021-11-11vue draggable resizable gorkys與v-chart使用與總結(jié)
這篇文章主要介紹了vue draggable resizable gorkys與v-chart使用與總結(jié),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09vue項(xiàng)目中封裝echarts的優(yōu)雅方式分享
在實(shí)際項(xiàng)目開發(fā)中,我們會經(jīng)常與圖表打交道,比如?訂單數(shù)量表、商品銷量表、會員數(shù)量表等等,它可能是以折線圖、柱狀圖、餅狀圖等等的方式來展現(xiàn),下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目中封裝echarts的優(yōu)雅方式的相關(guān)資料,需要的朋友可以參考下2022-03-03Vue??vuex配置項(xiàng)和多組件數(shù)據(jù)共享案例分享
這篇文章主要介紹了Vue??vuex配置項(xiàng)和多組件數(shù)據(jù)共享案例分享,文章圍繞Vue?Vuex的相關(guān)資料展開配置項(xiàng)和多組件數(shù)據(jù)共享的案例分享,需要的小伙伴可以參考一下2022-04-04VUE-Table上綁定Input通過render實(shí)現(xiàn)雙向綁定數(shù)據(jù)的示例
今天小編就為大家分享一篇VUE-Table上綁定Input通過render實(shí)現(xiàn)雙向綁定數(shù)據(jù)的示例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08