vue 实现多组合复选框案例

完成效果如图: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

回到顶部