The problem of multiple selection and inverse selection in Vue

topic description

complete the shopping cart, select the corresponding items and cancel the function

sources of topics and their own ideas

"Vue.js practice" Chapter 5

related codes

/ / Please paste the code text below (do not replace the code with pictures)

<!DOCTYPE html>
<html lang="cmn-hans">

<head>
    <meta charset="utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <!--PC   360webkit -->
    <meta name="renderer" content="webkit">
    <!--  for PC -->
    <link rel="stylesheet" type="text/css"  href="css.css">
    <title></title>
</head>

<body>
    <div>
        

<ol> <li></li> <li></li> <li></li> <li></li> </ol> </div> <hr> <!-- --> <div id="app" v-cloak> <template v-if="goods.length"> <table> <thead> <tr> <td></td> <td></td> <td></td> <td></td> <td></td> <td> | <input type="checkbox" @click="selectAll" id="selectAll" :checked="isCheckedAll"></td> </tr> </thead> <tbody> <tr v-for="good,index in goods"> <td>{{index+1}}</td> <td>{{good.name}}</td> <td>{{good.price}}</td> <!-- --> <td> <button @click="reduce(index)" :disabled="good.count === 1">-</button> {{good.count}} <button @click="add(index)">+</button> </td> <!-- --> <td> <button @click="remove(index)"></button> </td> <td> <input type="checkbox" @click="select(index,$event)" class="select"> </td> </tr> </tbody> </table> <div>

:{{totalPrice}}

: {{selectPrice}}

</div> </template> <div v-else></div> </div> <script src="https://unpkg.com/vue/dist/vue.min.js"></script> <script src="trolley.js"></script> </body> </html>

css.css:

table {
    border: 1px solid -sharpccc;
}

thead {
    background-color: -sharpddd;
}

td {
    border: 1px solid -sharpccc;
}

trolley.js:

var app = new Vue({
    el: "-sharpapp",
    data: {
        //
        goods: [
            { id: 1, name: "iphone 7", price: 6188, count: 1 },
            { id: 2, name: "ipad Pro", price: 5888, count: 1 },
            { id: 3, name: "MacBook Pro", price: 21488, count: 1 }
        ],
        selectPrice: 0,
        isCheckedAll: false ,//
        isChecked:false
    },
    computed: {
        totalPrice: function() {
            var total = 0;
            for (var i = 0; i < this.goods.length; iPP) {
                total += this.goods[i].price * this.goods[i].count;
            }
            return total;
        }
    },
    methods: {
        reduce: function(index) {
            // reduce 
            if (this.goods[index].count === 1) return;
            this.goods[index].count--;
        },
        add: function(index) {
            this.goods[index].countPP;
        },
        remove: function(index) {
            //
            this.goods.splice(index, 1);
        },
        selectAll: function() {
            if (this.isCheckedAll) {

                for (let i = 0; i < this.goods.length; iPP) {
                    document.querySelectorAll(".select")[i].checked = false;
                }
            } else {

                for (let i = 0; i < this.goods.length; iPP) {
                    document.querySelectorAll(".select")[i].checked = true;
                }
            }
            this.isCheckedAll = !this.isCheckedAll;
        },
        select: function(index, event) {

            if (document.querySelectorAll(".select")[index].checked) {
                document.querySelectorAll(".select")[index].checked = true;

                //






            } else {
                document.querySelectorAll(".select")[index].checked = false;


                      //

            }
        }
    },
});

what result do you expect? What is the error message actually seen?

at present, the functions of single selection and all selection have been completed, but in fact, in the course of operation, after selecting all buttons one by one, and deselecting them one by one, the full selection button will also be unchecked at last, which is not completed.
I think the idea should be to cycle through whether all checkbox is selected / unchecked every time you select / unselect, and then set the status of the select all button. But I don"t know how to write it.

Mar.25,2021

use watch or computed


to give you a like, the question steps are very clear.
you can use watch or computed to listen to the state, of the radio button to set whether the all button is selected or not.


var app = new Vue({
    el: '-sharpapp',
    data: {
        //
        goods: [
            { id: 1, name: 'iphone 7', price: 6188, count: 1 },
            { id: 2, name: 'ipad Pro', price: 5888, count: 1 },
            { id: 3, name: 'MacBook Pro', price: 21488, count: 1 }
        ],
        selectPrice: 0,
        isChecked:false,
        selectedList: []
    },
    computed: {
        totalPrice: function() {
            var total = 0;
            for (var i = 0; i < this.goods.length; iPP) {
                total += this.goods[i].price * this.goods[i].count;
            }
            return total;
        },
        isCheckedAll(){
            return this.selectedList.length === this.goods.length
        }
    },
    methods: {
        reduce: function(index) {
            // reduce 
            if (this.goods[index].count === 1) return;
            this.goods[index].count--;
        },
        add: function(index) {
            this.goods[index].countPP;
        },
        remove: function(index) {
            //
            this.goods.splice(index, 1);
        },
        selectAll: function() {
            if (this.isCheckedAll) {

                for (let i = 0; i < this.goods.length; iPP) {
                    document.querySelectorAll(".select")[i].checked = false;
                }
                this.selectedList = []
            } else {
                                this.selectedList = []
                for (let i = 0; i < this.goods.length; iPP) {
                    document.querySelectorAll(".select")[i].checked = true;
                    this.selectedList.push(i)
                }
            }
        },
        select: function(index, event) {
            let isSelected = document.querySelectorAll(".select")[index].checked
          let selectedIndex = this.selectedList.indexOf(index)
          
          if (isSelected && selectedIndex <= -1) {
                this.selectedList.push(index)
          } else if (!isSelected && selectedIndex > -1){
                this.selectedList.splice(selectedIndex, 1)
          }
        }
    },
});

other answers mention that you need to use computed, which is correct, because whether isCheckedAll needs to see changes in the values of each check "in real time", it is more appropriate to use computed.
simplifies your code by the way: first, you can design whether each item is selected or not as a goods field, so that the logic is clearer; second, the select and selectAll methods are rewritten for reference. The
code is as follows:

:{{checkedGoodIds.length}}</span>
        </div>
    </div>
</template>
<script>
    new Vue({
        data: {
            goods: [{
                id: 1,
                name: '1-xuanyuan1',
                checked: false
            }, {
                id: 2,
                name: '2-xuanyuan2',
                checked: false
            }, {
                id: 3,
                name: '3-xuanyuan3',
                checked: false
            }, {
                id: 4,
                name: '4-xuanyuan4',
                checked: false
            }, {
                id: 5,
                name: '5-xuanyuan5',
                checked: false
            }, {
                id: 6,
                name: '6-xuanyuan6',
                checked: false
            }],
        },
        computed:{
            // 
            isAllSelected(){
                return this.goods.every((el) => {
                    return el.checked;
                })
            },
            // id
            checkedGoodIds(){
                let filterArr = this.goods.filter((el) => {
                    return el.checked;
                });
                return filterArr.map((el) => {
                    return el.id;
                })
            }
        },
        methods: {
            // 
            allSelect() {
                let checked = true;
                // 
                if(this.isAllSelected){
                    checked = false;
                }
                this.goods = this.goods.map(el => {
                    el.checked = checked;
                    return el;
                })
            },
            // 
            singleSelect(row, index) {
                row.checked = !row.checked;
                this.goods.splice(index, 1, row);
            }
        }
    }).$mount('-sharpapp')
</script>
MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1b3dd60-40951.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1b3dd60-40951.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?