Vue 全选/取消全选,反选/取消反选

这是一个组件:

<template>
    <div>
        <div>
            <input type="checkbox" v-model="isCheckAll" @change="checkedAll"> 全选/取消全选
            <input type="checkbox" v-model="isCheckInverse" @change="checkedInverse"> 反选/取消反选
        </div>
        <div v-for="(list, index) in checkboxLists">
            <input type="checkbox" v-model="checkedLists" :value="list.id"> {{ list.product_name }}            
        </div>
        <div>全选/反选 状态:{{ isCheckAll }}</div>
        <div>选中列表:{{ checkedLists }}</div>
    </div>
</template>

<script>
    export default {
        data () {
            return {
                // 总数据
                checkboxLists: [
                    {
                        id: 1,
                        product_name: '银手链'
                    },
                    {
                        id: 2,
                        product_name: '银手镯'
                    },
                    {
                        id: 3,
                        product_name: '银耳环'
                    }
                ],
                // 是否全选
                isCheckAll: false,
                // 是否反选
                isCheckInverse: false,
                // 选中列表
                checkedLists: []
            }
        },
        methods: {
            // 全选/取消全选
            checkedAll () {
                // 初始化反选/取消反选
                this.isCheckInverse = false
                // 判断 全选/反选 是否点击
                if (this.isCheckAll) {
                    let arr = []
                    // 循环全部数据并push到一个数组中
                    this.checkboxLists.forEach(element => {
                        arr.push(element.id)
                    });
                    // 选中列表赋值,此时的arr已经是全部数据了,直接赋值就等于选中所有checkbox
                    this.checkedLists = arr
                } else {
                    // 如果 全选/反选 为假,则选中列表初始化
                    this.checkedLists = []
                }
            },
            // 反选/取消反选
            checkedInverse () {
                // 这里不能直接用this.xxx赋值,具体参考https://www.cnblogs.com/nonsec/p/9322359.html
                let tempArr = JSON.parse(JSON.stringify(this.checkboxLists))
                let arr = []
                var obj = {}

                // 先循环已勾选的,赋值给对象,对象key和value都为勾选的值
                for (const i in this.checkedLists) {
                    obj[this.checkedLists[i]] = this.checkedLists[i]
                }

                // 循环总的,然后判断上面对象的属性是否存在,如果存在则加入数组
                for (const j in tempArr) {
                    if (!obj.hasOwnProperty(tempArr[j].id)) {
                        arr.push(tempArr[j].id)
                    }
                }

                // 最后赋值,实现反选/取消反选功能
                this.checkedLists = arr
            }
        },
        watch: {
            // 监听选中列表属性,当选中列表发生变化时,会运行此方法
            checkedLists (newValue, oldValue) {
                // 每次运行时,判断当前选中列表中的数组个数是否等于全部数据的数组个数,如果到某一时刻全等,则全选按钮为选中
                if (newValue.length === this.checkboxLists.length) {
                    this.isCheckAll = true
                } else {
                    // 否则为全不选
                    this.isCheckAll = false
                }
            }
        }
    }
</script>