利用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>
相关推荐
码事漫谈14 分钟前
解决 Anki 启动器下载错误的完整指南
前端
im_AMBER34 分钟前
Web 开发 27
前端·javascript·笔记·后端·学习·web
蓝胖子的多啦A梦1 小时前
低版本Chrome导致弹框无法滚动的解决方案
前端·css·html·chrome浏览器·版本不同造成问题·弹框页面无法滚动
玩代码1 小时前
vue项目安装chromedriver超时解决办法
前端·javascript·vue.js
訾博ZiBo1 小时前
React 状态管理中的循环更新陷阱与解决方案
前端
StarPrayers.2 小时前
旅行商问题(TSP)(2)(heuristics.py)(TSP 的两种贪心启发式算法实现)
前端·人工智能·python·算法·pycharm·启发式算法
一壶浊酒..2 小时前
ajax局部更新
前端·ajax·okhttp
苏打水com2 小时前
JavaScript 面试题标准答案模板(对应前文核心考点)
javascript·面试
Wx-bishekaifayuan2 小时前
基于微信小程序的社区图书共享平台设计与实现 计算机毕业设计源码44991
javascript·vue.js·windows·mysql·pycharm·tomcat·php
DoraBigHead3 小时前
React 架构重生记:从递归地狱到时间切片
前端·javascript·react.js