vue 实现多组合复选框案例
完成效果如图:
当我们点击标题全选时 指定店铺所有商品都被选中,取消时全取消
当我们选择某店铺商品数量等于该店铺所有商品时,该店铺全选按钮被选中
废话不多说,代码呈上 欢迎给出更好的方案实现该功能
---------------------------------------------------- goods_select.vue ------------------------------------------------------------------
<template>
<div class="goods-select-box big-box">
<!--每个店铺的商品展示-->
<div class="goods-shopp-box" v-if="mallData.length>0" v-for="Malls in mallData" >
<div class="goods-shopp">
<span
:class="hasSelectArr.indexOf(Malls.Mall.id)>=0?'checks':'removeCheck'"
@click="checkAll(Malls.Mall.id)"
>
</span>
<i class="icons">赢</i>
<span class="shopping-name hrefColor">{{Malls.Mall.name}}</span>
</div>
<ul class="goods-detail-type">
<li class="detail-item" v-for="items in Malls.Mall_detail">
<span
:class="hasSelectArr.indexOf(items.id)>=0?'checks':'removeCheck'"
@click="checkOne(items.id,Malls.Mall.id)"
>
</span>
<div class="detail-item-text">
<div class="img-cont">
<img class="goods-img" :src="https://www.pianshen.com/article/2595281710/items.img">
</div>
<div class="intro-text">
<div class="intro-text-top">
<div class="text-top-left">
<p class="title">{{items.title}}</p>
<p class="detail-goods-intro hrefColor">{{items.num}}</p>
</div>
<div class="text-top-right">
{{items.compare}}
</div>
</div>
<p class="intro-text-bottom">{{items.rate}}</p>
</div>
</div>
</li>
</ul>
</div>
<div class="no-data" v-else>
空空如也
</div>
<!--btn next step-->
<button class="btn-next nav-and-btn">下一步</button>
</div>
</template>
<script>
import Datas from '../../../static/data.js'
export default {
data() {
return {
// 定义一个盛放已选的容器
hasSelectArr:[],
//接收后台返回的数据
mallData:[]
}
},
components: {
},
created(){
this.mallData = [...Datas];
},
mounted() {
},
methods: {
/*
* @fun :全选方法
* @params{id:商品识别id}
*/
checkAll(id){
let index = this.hasSelectArr.indexOf(id);
if( index>= 0 && this.hasSelectArr.length){
//1.将该id splice 移除
this.hasSelectArr = this.hasSelectArr.filter(s=>{
return s!= id;
});
//2.取消所有商品
this._fremoveAllGoods( id );
}else{
//1.将该id push到数组中
this.hasSelectArr.push( id );
//2.将含有该id类似名的商品存放到数组中
this._fgetGoodsId( id )
}
},
/*
* @fun :全选方法
* @params{id:商品识别id}
*/
_fgetGoodsId( id ){
this.mallData.forEach(item=>{
if(id===item.Mall.id){
item.Mall_detail.forEach(val=>{
if( this.hasSelectArr.indexOf(val.id)<0 ){
this.hasSelectArr.push(val.id)
}
})
}
})
},
/*
* @fun :取消全选方法
* @params{id:商品识别id}
*/
_fremoveAllGoods( id ){
var len = this.hasSelectArr.length,
indexs = '',
aimsId = '';
//注意这里不能使用index和splice来做 因为hasSelectArr的元素一直在变化 所以这里用filter过滤更合适
this.hasSelectArr = this.hasSelectArr.filter(val=>{
indexs = val.indexOf('_');
//这里要分两种情况 当有下划线时
if( indexs >-1){
aimsId = val.substring(0,indexs);
return aimsId!=id;
//当没有下划线时 我们不需要进行截取 直接返回不等于就好
}else if( indexs == -1 ){
return val!=id;
}
})
console.log(this.hasSelectArr)
},
/*
* @fun :单选
* @params{id:单个商品id,MallId:店铺的id}
*/
checkOne( id,MallId ){
var index = this.hasSelectArr.indexOf( id ),
MallIndex = this.hasSelectArr.indexOf( MallId ),
num = 0,
aims = '';
//1.当该商品已被选择 则我们就将其取消 同时如果全选被勾选 则我们也取消全选
if( index>=0 ){
this.hasSelectArr = this.hasSelectArr.filter(val=>{
return val != id;
}).filter( vals=>{
return vals != MallId;
})
}else{
//2.如果未被选择,则添加
this.hasSelectArr.push( id );
//3.假如所选商品的数量刚好等于后台传的数量则将全选勾上
if( MallIndex<0 ){
aims = id.substring(0,id.indexOf('_')+1)//获取同一个key来比对
this.hasSelectArr.map(item=>{
if( aims == item.substring(0,item.indexOf('_')+1) ){
num++;
}
});
if( num == this._fgetGoodsNum( MallId )){
this.hasSelectArr.push( MallId )
}
}
}
},
/*
* @fun :获取某店铺商品数
* @params{id:店铺id}
*/
_fgetGoodsNum( id ){
var len;
this.mallData.map(val=>{
if( id == val.Mall.id ){
len = val.Mall_detail.length;
}
})
return len;
}
},
}
</script>
<style scoped="scoped" lang="scss">
$btnNext: 50px;
@function px2rem($px) {
$rem: 37.5px;
@return ($px / $rem)+rem
}
/*选框 star*/
.checks,.removeCheck{
width: px2rem(20px);
height: px2rem(20px);
border-radius:50%;
margin-right: px2rem(12px);
}
.checks{
background-color: red;
/* background-image: url();*/
}
.removeCheck{
background-color: yellow;
/* background-image: url();*/
}
/*选框 end*/
.goods-select-box {
min-height: 100%;
padding-bottom: px2rem($btnNext);
}
.goods-shopp-box {
background-color: white;
margin-bottom: px2rem(10px);
padding: 0 px2rem(10px) 0 px2rem(10px);
border-bottom: 1px solid rgb(236, 236, 236);
}
.goods-shopp {
padding: px2rem(10px) px2rem(5px);
display: flex;
align-items: center;
border-bottom: 1px solid #ccc;
}
.inps {
margin-right: px2rem(12px);
}
.icons {
margin-right: px2rem(12px);
}
.goods-detail-type {
li:last-child {
border-bottom: none;
}
}
.detail-item {
display: flex;
align-items: center;
padding: px2rem(10px) 0 px2rem(10px) px2rem(5px);
border-bottom: 1px dashed #ccc;
}
.detail-item-text {
display: flex;
flex: 1;
max-height: 2.4rem;
}
.img-cont {
width: px2rem(100px);
/*height: 100%;*/
margin-right: px2rem(12px);
.goods-img {
display: inline-block;
width: 100%;
height: 100%;
}
}
.title {
font-size: 14px;
}
.intro-text {
flex: 1;
}
.intro-text-top {
display: flex;
justify-content: space-between;
width: 100%;
}
.text-top-right {
display: flex;
align-items: center;
}
.intro-text-bottom {
text-align: right;
}
/*下一步按钮*/
.btn-next {
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
font-size: 15px;
color: white;
border: none;
outline: none;
background-color: #fb474a;
}
</style>
--------------------------------------------------------------------模拟数据格式 -------------------------------------------------------------
import goodImg from "../src/assets/image/login/bgi.jpg"
const datas = [
{
Mall:{
name:"缤纷果园-花园路店",
id:"hk",
},
Mall_detail:[{
id:'hk_1',
img:goodImg,
title:'[自营] 越南火龙果',
num:'火龙果约500g/个',
compare:'赠菜豆30个',
rate:'x2'
},{
id:'hk_2',
img:goodImg,
title:'[自营] 越南火龙果',
num:'火龙果约500g/个',
compare:'赠菜豆30个',
rate:'x2'
},{
id:'hk_3',
img:goodImg,
title:'[自营] 越南火龙果',
num:'火龙果约500g/个',
compare:'赠菜豆30个',
rate:'x2'
}]
},
{
Mall:{
name:"缤纷果园-槐树路店",
id:"yy",
},
Mall_detail:[{
id:'yy_1',
img:goodImg,
title:'[自营] 越南MV果',
num:'MV果约50g/个',
compare:'赠菜豆30个',
rate:'x1'
},{
id:'yy_2',
img:goodImg,
title:'[自营] 越南MV果',
num:'MV果约50g/个',
compare:'赠菜豆30个',
rate:'x1'
},{
id:'yy_3',
img:goodImg,
title:'[自营] 越南MV果',
num:'MV果约50g/个',
compare:'赠菜豆30个',
rate:'x1'
}]
}
]
export default datas
以上是 vue 实现多组合复选框案例 的全部内容, 来源链接: utcz.com/a/60313.html