Vue购物车三级选中功能
人间小瓜瓜 人气:0最近在练习商城项目,记录下实现购物车三级选中的过程(小白一个,水平很菜)
效果图:
实现:
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接收父组件传值改变选中时的样式 // 商品的选中按钮 <cart-choose :chooseClass="$store.state.cartList[index].products[key].proChecked" @click.native.stop="proCheckedClick(index, key)" /> // 店铺的选择按钮 (我把店铺列表和商品分成了两个组件,index是传给店铺列表内商品的) <cart-choose :index="index" :chooseClass="$store.state.cartList[index].shopChecked" @click.native="shopCheckedClick(index)" /> // 全选按钮 <cart-choose :chooseClass="$store.state.allChecked" />
商品,店铺,全选按钮的点击方法
// 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 }); } } } },
最开始我是把这些代码都放在了三个方法里,这样写也能实现,但是看起来实在太乱了,而且不能追踪到具体是进行了什么操作。不想搞那么多方法的可以看看
// 单个商品选中 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;
加载全部内容