vue|vue 淘宝购物车实现三级选中

最近在练习商城项目,记录下实现购物车三级选中的过程(小白一个,水平很菜)
效果图:
vue|vue 淘宝购物车实现三级选中
文章图片

实现:
1.全选时所有商品+店铺全部选中;反之全部取消选中
2.店铺选中时,当前店铺内所有商品选中;反之取消选中
3.店铺内商品全选 → 所属店铺选中;反之取消选中店铺
4.店铺+所有商品全选 → 全选按钮选中;反之取消选中
首先说明一下,我使用了vuex来管理购物车数据,所有改变按钮状态的方法都写在mutaition里

const state = { cartList: [],// 购物车列表 totalCount: 0, allChecked: false,// 全选 shopCheckedNum: 0,// 选中的店铺数量 /** * cartList: [ *{ *shopName, *shopChecked: false,// 店铺选中 *proCheckedNum: 0,// 当前店铺商品选中数量 *cartGoodsInfo: [ *{iid,styleName,proChecked...}// 里边是商品的各种信息,proChecked是商品选中状态 *{...} *] *}, *{...} * ] */ };

html选择按钮部分
// 这是选择按钮,我把它封装成了一个组件chooseClass接收父组件传值改变选中时的样式 // 商品的选中按钮 // 店铺的选择按钮(我把店铺列表和商品分成了两个组件,index是传给店铺列表内商品的) // 全选按钮

商品,店铺,全选按钮的点击方法
// index:店铺索引值key:当前商品在当前店铺内的索引值 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; // 商品数量+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; // 店铺数量+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里
// 商品状态 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); } // 商品没全选 → 如果店铺选中改为未选中 // (不加这个判断条件的话 本来没选中的店铺也会执行shopCheckedFalse,导致商品选中数量会-1) else if (cartList[index].shopChecked) { commit("shopCheckedFalse", index); }// 判断店铺是否全选,改变全选按钮状态 if (state.shopCheckedNum === cartList.length) { commit("allCheckedTrue"); } else { commit("allCheckedFalse"); } }, // 店铺选中状态 ShopChecked({ state, commit }, index) { const cartList = state.cartList; if (!cartList[index].shopChecked) { // 让店铺选中 → 将当前店铺内未选中的商品改为选中 commit("shopCheckedTrue", index); for (let k in cartList[index].products) { if (!cartList[index].products[k].proChecked) { commit("proCheckedTrue", { index, key: k }); } } } else { // 店铺取消选中 → 将当前店铺内所有商品改为未选中 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 }); } } } },

【vue|vue 淘宝购物车实现三级选中】最开始我是把这些代码都放在了三个方法里,这样写也能实现,但是看起来实在太乱了,而且不能追踪到具体是进行了什么操作。不想搞那么多方法的可以看看
// 单个商品选中 ProChecked(state, { index, key }) { const cartList = state.cartList; // 商品选中状态取反 cartList[index].products[key].proChecked = !cartList[index].products[key].proChecked; // 如果选中,选中数量+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--; } // 判断店铺是否全选,改变全选按钮状态 if (state.shopCheckedNum === cartList.length) { state.allChecked = true; } else { state.allChecked = false; } }, // 店铺选中 ShopChecked(state, index) { const cartList = state.cartList; // 取反 cartList[index].shopChecked = !cartList[index].shopChecked; // 如果选中,选中数量+1,取消选中则-1 if (cartList[index].shopChecked) { state.shopCheckedNum++; } else { state.shopCheckedNum--; }// 遍历当前店铺商品列表 for (let i in cartList[index].products) { // 如果店铺被选中,所有商品改为选中状态,并且更改选中数量 if (cartList[index].shopChecked) { cartList[index].products[i].proChecked = true; cartList[index].proCheckedNum = cartList[index].products.length; } else { // 店铺取消选中,所有商品取消选中,选中数量为0 cartList[index].products[i].proChecked = false; cartList[index].proCheckedNum = 0; } }// 店铺列表全选,全选按钮选中 if (state.shopCheckedNum === cartList.length) { state.allChecked = true; } else { state.allChecked = false; } }, // 全选 AllChecked(state) { const cartList = state.cartList; state.allChecked = !state.allChecked; // 选中,全部店铺列表,商品选中,店铺,商品选中数量改变 for (let i in cartList) { for (let k in cartList[i].products) { if (state.allChecked) {cartList[i].shopChecked = true; state.shopCheckedNum = cartList.length; cartList[i].products[k].proChecked = true; cartList[i].proCheckedNum = cartList[i].products.length; } else { // 取消选中,所有店铺列表,商品取消选中,数量为0 cartList[i].shopChecked = false; state.shopCheckedNum = 0; cartList[i].products[k].proChecked = false; cartList[i].proCheckedNum = 0; } } } },

    推荐阅读