vue中实现双层全选反选(类似淘宝购物车)

223 阅读2分钟

一、静态数据

let car = [
        {
            "name": "二小姐的店",
            "shop_id": 1,
            "prolists": [
                {
                    "pro_id": 202111810,
                    "pro_title": "e码当鲜 带鱼900g(总共6条)",
                    "pro_indr": "e码当鲜 带鱼900g(总共6条)",
                    "type_n": 2,
                    "pro_img": "https://Img.iblimg.com/photo-59/3020/1582176048_160x160.jpg",
                    "pro_price": "222",
                    "pro_hot": 0,
                    "mark_id": 1,
                    "phone": "400-667-0519",
                    "pro_unit": "斤",
                    "pro_place": "盐城",
                    "pro_num": 1
                },
                {
                    "pro_id": 202111830,
                    "pro_title": "卫龙辣条鱼豆腐香辣麻辣混合味180g休闲零食品豆干办公室网红小吃",
                    "pro_indr": "undefined",
                    "type_n": 4,
                    "pro_img": "https://img.alicdn.com/imgextra/i3/725677994/O1CN01W3aEnq28vIrXqpKJf_!!725677994.jpg_430x430q90.jpg",
                    "pro_price": "11.90",
                    "pro_hot": 1,
                    "mark_id": 2,
                    "phone": "17625897426",
                    "pro_unit": "斤",
                    "pro_place": "江苏苏州",
                    "pro_num": 2
                }
            ]
        },
        {
            "name": "瓦乡鸡",
            "shop_id": 2,
            "prolists": [
                {
                    "pro_id": 202111815,
                    "pro_title": "来伊份 清风飘香卤香味优品蛋干",
                    "pro_indr": "来伊份 清风飘香卤香味优品蛋干",
                    "type_n": 4,
                    "pro_img": "https://Img.iblimg.com/photo-42/2000/743275208_160x160.jpg",
                    "pro_price": "222",
                    "pro_hot": 0,
                    "mark_id": 1,
                    "phone": "400-667-0519",
                    "pro_unit": "斤",
                    "pro_place": "盐城",
                    "pro_num": 2
                },
                {
                    "pro_id": 202111824,
                    "pro_title": "良品铺子甜辣味豆干160g素食网红零食办公室辣豆腐干小吃休闲食品",
                    "pro_indr": "undefined",
                    "type_n": 4,
                    "pro_img": "https://img.alicdn.com/imgextra/i2/725677994/O1CN0118i1QB28vIp1C6YpS_!!725677994-0-sm.jpg_430x430q90.jpg",
                    "pro_price": "18.9",
                    "pro_hot": 1,
                    "phone": "17625897426",
                    "pro_unit": "斤",
                    "pro_place": "江苏无锡",
                    "pro_num": 1
                },
                {
                    "pro_id": 202111884,
                    "pro_title": "沃隆 每日坚果750g成人款(25g*30袋)坚果炒货休闲零食大礼包 节日礼盒 混合坚果健康零食",
                    "pro_indr": "沃隆 每日坚果750g成人款(25g*30袋)坚果炒货休闲零食大礼包 节日礼盒 混合坚果健康零食",
                    "type_n": 3,
                    "pro_img": "https://img20.360buyimg.com/babel/s320x320_jfs/t1/107917/16/12145/259287/5e9414a6Eeb5c5c9a/68fad117c2c1b5e6.jpg!cc_320x320.webp",
                    "pro_price": "139",
                    "pro_hot": 1,
                    "mark_id": 2,
                    "phone": "0",
                    "pro_unit": "袋",
                    "pro_place": "南京",
                    "pro_num": 2
                }
            ]
        }
    ]

二、功能模块代码

1.计算价格

            // 计算所有选中商品的价格
            noun() {
                let amount = 0;
                for (let i in this.car) {
                    for(let y in this.car[i].prolists) {
                        if(this.car[i].prolists[y].twoCheck == true){
                            amount += this.car[i].prolists[y].pro_num * Number(this.car[i].prolists[y].pro_price)
                        }
                    }
                
                }
                this.all = amount
         
            },

2.店内全部商品选中则店铺选中,店铺全部选中则全选选中

            // index父 索引  i子索引
            // 店内商品全部选中则店铺选中
            twoCheckF(twoCheck, index, i) {
                let sum = 0
                if (twoCheck == true) {
                    this.car[index].prolists[i].twoCheck = true
                    
                    
                    //检索某店铺内的所有商品是否都选中
                    let f = this.car[index].prolists.every(item => {
                        return item.twoCheck == true
                    })

                    this.car[index].oneCheck = f;

                    // 检索全部店铺是否都选中
                    let f1 = this.car.every(item => {
                        return item.oneCheck == true
                    })

                    this.allchoose = f1;

                    

                } else {
                    this.car[index].prolists[i].twoCheck = false

                    //检索某店铺内的所有商品是否都选中
                    let f = this.car[index].prolists.every(item => {
                        return item.twoCheck == true
                    })
                    this.car[index].oneCheck = f;
                    

                    // 检索全部店铺,所有商品是否都选中
                    let f1 = this.car.every(item => {
                        return item.oneCheck == true
                    })

                    this.allchoose = f1;


                }
               this.noun()

            },

3.店铺选中则店内全部商品选中,店铺全部选中则全选选中

            oneCheckF(oneCheck,index) {
                // 店铺全部选中 ,则该店铺内的商品全部选中
                if(oneCheck == true){
                    this.car[index].oneCheck = true
                    for(let x in this.car[index].prolists){
                        this.car[index].prolists[x].twoCheck = true;
                    }
                  
                }else{
                    for(let x in this.car[index].prolists){
                        this.car[index].oneCheck = false
                        this.car[index].prolists[x].twoCheck = false;
                    }
                    
                }
                this.noun()

                // 店铺全部选中,则全选选中
                let f = this.car.every(item => {
                    return item.oneCheck == true
                })
                this.allchoose = f;
            },

4.全选

            allChange() {
                // 全选选中,则全部商品选中
                if(this.allchoose == true) {
                    for(let i in this.car) {
                        this.car[i].oneCheck = true;
                        for(let j in this.car[i].prolists) {
                            this.car[i].prolists[j].twoCheck = true;
                        }
                    }
                   
                }else{
                    for(let i in this.car) {
                        this.car[i].oneCheck = false;
                        for(let j in this.car[i].prolists) {
                            this.car[i].prolists[j].twoCheck = false;
                        }
                    }
                 
                }
                this.noun()
            },

5.商品数量加1减1

            add(index,i){
                this.car[index].prolists[i].pro_num++;
                this.noun();
            },
            cut(index,i){
                this.car[index].prolists[i].pro_num--;
                this.noun();
            }

三、完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="./data.js"></script>
    <style>
        @import url(./comm.css);
    </style>
</head>

<body>

    <!-- <div id="app">
        <car-tem></car-tem> -->
        <!-- <footer>
            <div v-for="(nav,index) in navlist" :key="index" :class="index ==n ?'nav-active' :''">{{nav}}</div>
            
        </footer> -->
    <!-- </div> -->


    <template id="car">
        <div>
            <div>
                <input type="checkbox" v-model="allchoose" @change="allChange"/>全选
                <span>{{all.toFixed(2)}}</span>
            </div>
            <ul>
                <li v-for="(item,index) in car" :key="item.shop_id">
                    <p style="color:red">
                        <!-- 店铺的复选框 -->
                        <input type="checkbox" v-model="item.oneCheck" @change="oneCheckF(item.oneCheck,index)" />
                        {{item.name}}
                    </p>
                    <ul class="lis">
                        <li v-for="(child,i) in item.prolists" style="background:#f6f6f6">
                            <!-- 商品的复选框 -->
                            <input type="checkbox" v-model="child.twoCheck"
                                @change="twoCheckF(child.twoCheck,index,i)" />
                            <div>
                                <img :src="child.pro_img" />
                                <span style="color:red">¥{{child.pro_price}}</span>
                            </div>
                            <div>
                                <span @click="cut(index,i)">-</span>
                                <input type="number" v-model="child.pro_num" />
                                <span @click="add(index,i)">+</span>
                            </div>
                        </li>
                    </ul>
                    <!-- 购物 -->
                </li>
            </ul>
        </div>
    </template>
    <script>
        // axios.defaults.baseURL = 'http://192.168.2.21:8088/'
        Vue.component('carTem', {
            template: "#car",
            data() {
                return {
                    all: 0,//总价
                    car: car, //从js引入
                    allchoose: false, //全选默认状态是不选中
                }
            },
            created() {
               /*  axios({
                    url: '/api/listcars'
                }).then(res => {
                    //    梳理数据源的过程
                    res.data.data.data.forEach(item => {
                        item.oneCheck = false;  // 店铺默认不选中
                        item.prolists.forEach(child => {
                            child.twoCheck = false;  // 商品默认不选中
                        })
                    })
                    this.car = res.data.data.data
                }) */
                car.forEach(item => {
                    item.oneCheck = false;
                    item.prolists.forEach(child => {
                        child.twoCheck = false;
                    })
                })
            },
            methods: {
                // 计算所有选中商品的价格
                noun() {
                    let amount = 0;
                    for (let i in this.car) {
                        for(let y in this.car[i].prolists) {
                            if(this.car[i].prolists[y].twoCheck == true){
                                amount += this.car[i].prolists[y].pro_num * Number(this.car[i].prolists[y].pro_price)
                            }
                        }
                    
                    }
                    this.all = amount
             
                },

                // index父 索引  i子索引
                // 店内商品全部选中则店铺选中
                twoCheckF(twoCheck, index, i) {
                    let sum = 0
                    if (twoCheck == true) {
                        this.car[index].prolists[i].twoCheck = true
                        
                        
                        //检索某店铺内的所有商品是否都选中
                        let f = this.car[index].prolists.every(item => {
                            return item.twoCheck == true
                        })

                        this.car[index].oneCheck = f;

                        // 检索全部店铺是否都选中
                        let f1 = this.car.every(item => {
                            return item.oneCheck == true
                        })

                        this.allchoose = f1;

                        

                    } else {
                        this.car[index].prolists[i].twoCheck = false

                        //检索某店铺内的所有商品是否都选中
                        let f = this.car[index].prolists.every(item => {
                            return item.twoCheck == true
                        })
                        this.car[index].oneCheck = f;
                        

                        // 检索全部店铺,所有商品是否都选中
                        let f1 = this.car.every(item => {
                            return item.oneCheck == true
                        })

                        this.allchoose = f1;


                    }
                   this.noun()

                },
                allChange() {
                    // 全选选中,则全部商品选中
                    if(this.allchoose == true) {
                        for(let i in this.car) {
                            this.car[i].oneCheck = true;
                            for(let j in this.car[i].prolists) {
                                this.car[i].prolists[j].twoCheck = true;
                            }
                        }
                       
                    }else{
                        for(let i in this.car) {
                            this.car[i].oneCheck = false;
                            for(let j in this.car[i].prolists) {
                                this.car[i].prolists[j].twoCheck = false;
                            }
                        }
                     
                    }
                    this.noun()
                },
                oneCheckF(oneCheck,index) {
                    // 店铺全部选中 ,则该店铺内的商品全部选中
                    if(oneCheck == true){
                        this.car[index].oneCheck = true
                        for(let x in this.car[index].prolists){
                            this.car[index].prolists[x].twoCheck = true;
                        }
                      
                    }else{
                        for(let x in this.car[index].prolists){
                            this.car[index].oneCheck = false
                            this.car[index].prolists[x].twoCheck = false;
                        }
                        
                    }
                    this.noun()

                    // 店铺全部选中,则全选选中
                    let f = this.car.every(item => {
                        return item.oneCheck == true
                    })
                    this.allchoose = f;
                },

                add(index,i){
                    this.car[index].prolists[i].pro_num++;
                    this.noun();
                },
                cut(index,i){
                    this.car[index].prolists[i].pro_num--;
                    this.noun();
                }

            }
        })
        let app = new Vue({
            data: {
                /* navlist: ["首页", "分类", "购物车", "我的"],
                n: 2 */
            }
        })
        app.$mount('#app')
    </script>
</body>

</html>