猿问

关于vue中的watch属性的请教,如下图和代码

问题

1.想要蓝色框中的checkbox都是选中状态的时候,红色框中显示为true
2.已经通过methods实现
3.请问用watch如何实现

代码

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        
        .app-cart {
            padding-bottom: 100px;
            background-color: #f5f5f5;
        }
        
        .app-cart .cart-header {
            height: 40px;
            line-height: 40px;
            text-align: center;
            border-bottom: 1px solid #ccc;
        }
        
        .cart-main .main-item {
            margin-bottom: 10px;
            background-color: #fff;
            box-sizing: border-box;
            border-top: 1px solid #ccc;
            border-bottom: 1px solid #ccc;
        }
        
        .cart-main .main-item .item-top {
            display: flex;
            align-items: center;
            height: 40px;
            box-sizing: border-box;
            border-bottom: 1px solid #ccc;
        }
        
        .cart-main .main-item .item-top input {
            flex: 0 0 50px;
            width: 50px;
        }
        
        .cart-main .main-item .item-top span {
            flex: 1;
        }
        
        .cart-main .main-item .item-middle .middle-list {
            display: flex;
            box-sizing: border-box;
            border-bottom: 1px solid #ccc;
        }
        
        .cart-main .main-item .item-middle .middle-list .list-left {
            flex: 0 0 50px;
            width: 50px;
            text-align: center;
        }
        
        .cart-main .main-item .item-middle .middle-list .list-center {
            flex: 0 0 100px;
            width: 100px;
        }
        
        .cart-main .main-item .item-middle .middle-list .list-right {
            display: flex;
            flex-direction: column;
            flex: 1;
        }
        
        .cart-main .main-item .item-footer {
            display: flex;
            align-items: center;
            justify-content: space-between;
            height: 40px;
            border-top: 1px solid #ccc;
        }
        
        .cart-footer {
            position: fixed;
            left: 0;
            bottom: 60px;
            width: 100%;
            height: 50px;
            display: flex;
            background-color: #fff;
            box-sizing: border-box;
            border-top: 1px solid #ccc;
        }
        
        .cart-footer .footer-left {
            flex: 0 0 50px;
            width: 50px;
            display: flex;
            align-items: center;
            margin-left: 20px;
        }
        
        .cart-footer .footer-center {
            flex: 1;
            text-align: right;
        }
        
        .cart-footer .footer-right {
            flex: 0 0 100px;
            width: 100px;
            background-color: #ff0000;
            color: #fff;
        }
    </style>

</head>

<body>
    <div id="app">
        <div class="app-cart">
            <header class="cart-header">购物车</header>
            <main class="cart-main">
                <div v-for="item1 in cartData" :key="item1.id" class="main-item">
                    <div class="item-top">
                        <input type="checkbox" v-model="item1.checked" @change="selectItem1(item1)">
                        <span>{{item1.shop_name}}</span>
                    </div>
                    <div class="item-middle">
                        <div v-for="(item2,index2) in item1.goodsList" :key="item2.id" class="middle-list">
                            <div class="list-left">
                                <input type="checkbox" @change="selectItem2(item1)" v-model="item2.checked">
                            </div>
                            <div class="list-center">
                                <!-- <img v-lazy="IMAGESURL + item2.goods_img"> -->
                            </div>
                            <div class="list-right">
                                <p>{{item2.goods_name}}</p>
                                <div>
                                    <span>单价:{{item2.goods_price}}</span>
                                    <span>数量:{{item2.cart_goods_number}}</span>
                                </div>
                                <p>总价:{{item2.goods_price*item2.cart_goods_number}}</p>
                            </div>
                        </div>

                    </div>
                </div>
            </main>
            <footer class="cart-footer">
                <div class="footer-left">
                    <input type="checkbox" v-model="checkAll" @change="selectAll">
                    <p>全选</p>
                </div>
                <div class="footer-center">
                    合计:{{allPrice}}
                </div>
                <div class="footer-right">
                    结算
                </div>
            </footer>
            <div>watch:{{bb}}</div>
        </div>
    </div>

    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    bb: "",
                    cartData: [{
                        shop_id: 4,
                        shop_name: "honor之家",
                        checked: false,
                        goodsList: [{
                            cart_goods_number: 3,
                            goods_name: "honor7x",
                            goods_img: "honor7x.png",
                            goods_price: 1299,
                            goods_id: 3,
                            checked: false
                        }, {
                            cart_goods_number: 2,
                            goods_name: "honor6x",
                            goods_img: "honor6x.png",
                            goods_price: 1199,
                            goods_id: 4,
                            checked: false
                        }, {
                            cart_goods_number: 5,
                            goods_name: "honor5x",
                            goods_img: "honor5x.png",
                            goods_price: 1099,
                            goods_id: 5,
                            checked: false
                        }]
                    }, {
                        shop_id: 1,
                        shop_name: "iPhone之家",
                        checked: false,
                        goodsList: [{
                            cart_goods_number: 1,
                            goods_name: "iPhonex",
                            goods_img: "iPhonex.png",
                            goods_price: 8888,
                            goods_id: 1,
                            checked: false
                        }]
                    }],
                    allPrice: 0,
                    checkAll: false
                };
            },
            methods: {
                // 全选
                selectAll() {
                    this.cartData.forEach(item => {
                        item.checked = this.checkAll;
                        item.goodsList.forEach(item => {
                            item.checked = this.checkAll;
                        });
                    });
                    if (this.checkAll == false) {
                        this.allPrice = 0;
                    }
                },
                // 第一层选择
                selectItem1(item1) {
                    item1.goodsList.forEach(i => {
                        i.checked = item1.checked;
                    });
                },
                // 第二层选择
                selectItem2(item1) {
                    let item1Price = 0;
                    let lengths = item1.goodsList.length;
                    let checkeds = item1.goodsList.filter(i => {
                        return i.checked == true;
                    });
                    if (lengths == checkeds.length) {
                        item1.checked = true;
                    } else {
                        item1.checked = false;
                    }
                    checkeds.forEach(item => {
                        this.allPrice += item.goods_price * item.cart_goods_number;
                    });
                    
                    //通过事件来监听,如果全部选中为true,否则为false
                    this.bb = this.cartData.every(item1 => {
                        return item1.goodsList.every(item2 => {
                            return item2.checked == true;
                        })
                    })
                },

            },
            watch: {
                bb: function() {
                    this.bb = this.cartData.every(item1 => {
                        return item1.goodsList.every(item2 => {
                            return item2.checked == true;
                        })
                    })
                }
            }
        })
    </script>
</body>

</html>
蓝山帝景
浏览 679回答 4
4回答

牧羊人nacy

你应该 watch 的是 cartData, 判断是否为全选中状态来设置 bb

波斯汪

一个计算属性不就搞定了么
随时随地看视频慕课网APP
我要回答