@TOC
👍 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!
0.前期提要
本文主要是实现做一个购物车的复选框多选
这次使用的前端框架是vue3,ui框架是element ui plus
在这个页面中,简单分析一下这里需要实现的功能:全选,反选,单选,多选,半选
这里的组件主要用到了Checkbox 多选框
1.商品选择
首先我们来做购物车的复选框(或者叫多选框模块),这里利用到了element ui plus的Checkbox 多选框组件,所以说记得按需引入和使用 Checkbox和CheckboxGroup (当然如果你是全部引入就不用管了) 当你将这个多选框组件复制过来就会显示出这个效果 (这里需要注意是从官方文档复制过来的代码是ts的,所以我这里也给出一下js的版本)
javascript
<template>
<el-checkbox
v-model="checkAll"
:indeterminate="isIndeterminate"
@change="handleCheckAllChange"
>
Check all
</el-checkbox>
<el-checkbox-group
v-model="checkedCities"
@change="handleCheckedCitiesChange"
>
<el-checkbox v-for="city in cities" :key="city" :label="city" :value="city">
{{ city }}
</el-checkbox>
</el-checkbox-group>
</template>
<script setup>
import { ref } from 'vue'
const checkAll = ref(false)
const isIndeterminate = ref(true)
const checkedCities = ref(['Shanghai', 'Beijing'])
const cities = ['Shanghai', 'Beijing', 'Guangzhou', 'Shenzhen']
const handleCheckAllChange = (val) => {
checkedCities.value = val ? cities : []
isIndeterminate.value = false
}
const handleCheckedCitiesChange = (value) => {
const checkedCount = value.length
checkAll.value = checkedCount === cities.length
isIndeterminate.value = checkedCount > 0 && checkedCount < cities.length
}
</script>
然后这里就是一层级的全选,但是淘宝的购物车页面是有2个层级的全选,第一个是全选是全部店铺的全部商品,第二个全选是一个店铺的全部商品
这里在淘宝这个购物车页面中,当选中了店铺时,第一层级的全选是不会变为半选的,我这里做了一下变化。然后划分为以下三种情况。
1.当选中所有店铺时,店铺1和2及其商品全选
2.当选中店铺1时,商品1-3全选,所有店铺半选
3.当选中商品1时,店铺1半选,所有店铺半选
2.实现
显示(html): 为了实现有2个层级的选择,就是需要一个嵌套循环遍历,遍历店铺列表和遍历商品列表出现多选框,多个选择的就需要用checkbox-group。
数据 (data): checkAllShops:控制是否全选所有店铺的状态。
shops:包含店铺的信息,包括每个店铺的全选状态 (checkAll)、已选中商品 (checkedProducts)、商品列表 (products)、和半选状态 (isIndeterminate)。
isIndeterminateAll:控制全选所有店铺复选框的半选状态。 方法 (methods): handleCheckAllShopsChange:当全选所有店铺的复选框状态改变时触发,更新每个店铺的全选状态和商品选中列表,取消店铺的半选状态,并调用 updateCheckAllShopsState 更新全选所有店铺的状态。
handleCheckAllProductsChange:当全选单个店铺的复选框状态改变时触发,更新该店铺的商品选中列表,取消该店铺的半选状态,并调用 updateCheckAllShopsState 更新全选所有店铺的状态。
handleCheckedProductsChange:当单个店铺的商品选中状态改变时触发,计算已选中商品数量,更新该店铺的全选和半选状态,并调用 updateCheckAllShopsState 更新全选所有店铺的状态。
updateCheckAllShopsState:更新全选所有店铺的状态,根据每个店铺的全选和半选状态来设置 checkAllShops 和 isIndeterminateAll 的值,确保在任何情况下都能正确更新全选和半选状态。
3.实现代码
javascript
<template>
<div>
<!-- 全选所有店铺的复选框 -->
<el-checkbox :indeterminate="isIndeterminateAll" v-model="checkAllShops" @change="handleCheckAllShopsChange">所有店铺</el-checkbox>
<div style="margin: 15px 0;"></div>
<!-- 循环遍历店铺列表 -->
<div v-for="shop in shops" :key="shop.id">
<div>
<!-- 全选单个店铺的复选框 -->
<el-checkbox :indeterminate="shop.isIndeterminate" v-model="shop.checkAll" @change="handleCheckAllProductsChange(shop)">{{ shop.name }}</el-checkbox>
</div>
<!-- 该店铺的商品列表 -->
<el-checkbox-group v-model="shop.checkedProducts" @change="handleCheckedProductsChange(shop)">
<el-checkbox v-for="product in shop.products" :label="product" :key="product">{{ product }}</el-checkbox>
</el-checkbox-group>
</div>
</div>
</template>
<script>
import { ref, reactive} from 'vue';
export default {
name: 'ShoppingCart',
setup() {
const checkAllShops = ref(false);
const shops = reactive([
{
id: 1,
name: '店铺1',
checkAll: false,
checkedProducts: [],
products: ['商品1', '商品2', '商品3'],
isIndeterminate: false
},
{
id: 2,
name: '店铺2',
checkAll: false,
checkedProducts: [],
products: ['商品4', '商品5', '商品6'],
isIndeterminate: false
}
]);
const isIndeterminateAll = ref(false);
// 当全选所有店铺复选框状态改变时触发
const handleCheckAllShopsChange = (val) => {
shops.forEach(shop => {
shop.checkAll = val;
shop.checkedProducts = val ? [...shop.products] : [];
shop.isIndeterminate = false;
});
updateCheckAllShopsState();
};
// 当全选单个店铺复选框状态改变时触发
const handleCheckAllProductsChange = (shop) => {
shop.checkedProducts = shop.checkAll ? [...shop.products] : [];
shop.isIndeterminate = false;
updateCheckAllShopsState();
};
// 当单个店铺的商品选中状态改变时触发
const handleCheckedProductsChange = (shop) => {
const checkedCount = shop.checkedProducts.length;
shop.checkAll = checkedCount === shop.products.length;
shop.isIndeterminate = checkedCount > 0 && checkedCount < shop.products.length;
updateCheckAllShopsState();
};
// 更新全选所有店铺的状态
const updateCheckAllShopsState = () => {
const totalShops = shops.length;
const checkedShopsCount = shops.filter(shop => shop.checkAll).length;
const anyShopIndeterminate = shops.some(shop => shop.isIndeterminate || (shop.checkedProducts.length > 0 && shop.checkedProducts.length < shop.products.length));
checkAllShops.value = checkedShopsCount === totalShops;
isIndeterminateAll.value = !checkAllShops.value && (checkedShopsCount > 0 || anyShopIndeterminate);
};
return {
checkAllShops,
shops,
isIndeterminateAll,
handleCheckAllShopsChange,
handleCheckAllProductsChange,
handleCheckedProductsChange
};
}
};
</script>