实现购物车中带有分类或者店铺名的全选和反选 , 主要用到了watch监听
- 案例效果截图
- 代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
background-color: #ccc;
}
.dp_title {
background-color: cadetblue;
height: 50px;
line-height: 50px;
color: #ffffff;
}
.dp_item {
margin-left: 20px;
}
</style>
</head>
<body>
<div id="app">
<ul>
<!-- 循环店铺 -->
<li v-for="(item,index) in list">
<div class="dp_title">
<!-- 店铺 -->
<input
type="checkbox"
v-model="item.flag"
@click="dp_title(item,$event)"
/><span>{{item.title}}</span>
</div>
<!-- 店铺商品 -->
<div class="dp_item" v-for="(subItem,subIndex) in item.arr">
<input type="checkbox" v-model="subItem.flag" />
<span>{{subItem.name}}</span>
</div>
</li>
</ul>
<!-- 全选 -->
<div><input type="checkbox" v-model="checkAll" @click="checkAll_click" />全选</div>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
checkAll: false, // 全选和反选
// 商品的数据
list: [
{
title: "小智的男装店",
id: 01,
flag: false,
arr: [
{
name: "鞋子",
pid: 3242131,
flag: false,
},
{
name: "帽子",
pid: 23231343,
flag: false,
},
],
},
{
title: "miss的零食店",
id: 02,
flag: false,
arr: [
{
name: "瓜子",
pid: 13123,
flag: false,
},
{
name: "二手车",
pid: 33123,
flag: false,
},
],
},
],
},
watch: { // 发现计算属性不是很好实现
list: {
deep: true, // 表示深度监听数据
handler(newVal, val) {
// ------------------点击单个店铺 实现店铺下的商品进行全选和反选---------------
// 1. 遍历数据 找出被选中的店铺
this.list.forEach((item) => {
// 2. 过滤店铺下的商品, flag :判断已选中商品的长度 是否等于 店铺下商品的长度
let flag =
item.arr.filter((sub_item) => sub_item.flag).length ==
item.arr.length;
// 3. 如果两者相等则将店铺的选中状态变为true
if (flag) {
item.flag = flag;
} else {
// 4. 否则 false
item.flag = false;
}
});
// ------------------- 底部全选框的全选反选 ---------------------
// 1. 过滤出来已选中的店铺
let dp_checked = this.list.filter((item) => item.flag);
// 2. 判断已选中的店铺长度是否等于购物车店铺的长度
if (dp_checked.length === this.list.length) {
// 3. 如果两者相等则将全选状态变为 true , 否则为false
this.checkAll = true;
} else {
this.checkAll = false;
}
},
},
// ----------------------- 监听全选按钮的状态 ----------------------
checkAll(newVal, val) {
// 1. 如果为true 则遍历所有的状态都为true
if (newVal) {
this.list.forEach((item) => {
item.arr.forEach((subItem) => {
subItem.flag = newVal;
});
});
}
},
},
methods: {
// ------------------- 点击店铺的复选框进行数据改变 ------------------
dp_title(item, el) {
// 1. 点击店铺的复选框改变店铺下的商品的状态
item.arr.forEach((subItem) => {
subItem.flag = el.target.checked;
});
},
// ------------------- 点击底部全选按钮 ------------------
checkAll_click(el){
// 1. 如果是 用户手动 点击底部取消全选的话,才全部取消选择
if(!el.target.checked){
this.list.forEach((item) => {
item.arr.forEach((subItem) => {
subItem.flag =el.target.checked ;
});
});
}
}
}
});
</script>
</body>
</html>