利用vue3+element ui plus做一个购物车的复选框多选

@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>
相关推荐
WeiXiao_Hyy9 分钟前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡26 分钟前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone31 分钟前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09011 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king1 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳2 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵2 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星2 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_3 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js