Javascript 如何管理Vue.js复选框组件上的复杂状态行为?

Javascript 如何管理Vue.js复选框组件上的复杂状态行为?,javascript,vue.js,vuejs2,vue-component,Javascript,Vue.js,Vuejs2,Vue Component,在为期一周的Vue.js学习中,我有几个挑战要克服。请注意,这实际上是围绕一个名为的父组件进行的,这并不有趣,因此我在本文中简化了代码 如何将某些项目设置为加载时默认选中 编辑-我算出了1。只需做[“鸡肉”、“火鸡”、“牛肉”、“鱼”、“猪肉”] 我如何取消选中某些项目,例如如果我选择了素食主义者,肉类选项应该取消选中 如何在选项旁边设置“排除”和“包括”复选框 复选框 <div id="questionnaire"> <checkbox v-model="form.me

在为期一周的Vue.js学习中,我有几个挑战要克服。请注意,这实际上是围绕一个名为
的父组件进行的,这并不有趣,因此我在本文中简化了代码

  • 如何将某些项目设置为加载时默认选中
  • 编辑-我算出了1。只需做
    [“鸡肉”、“火鸡”、“牛肉”、“鱼”、“猪肉”]

  • 我如何取消选中某些项目,例如如果我选择了素食主义者,肉类选项应该取消选中
  • 如何在选项旁边设置“排除”和“包括”复选框
  • 复选框

    <div id="questionnaire">
      <checkbox v-model="form.meats" id="8a"  option="Chicken"></checkbox>
      <checkbox v-model="form.meats" id="8b" option="Turkey"></checkbox>
      <checkbox v-model="form.meats" id="8c" option="Beef"></checkbox>
      <checkbox v-model="form.meats" id="8d" option="Pork"></checkbox>
      <checkbox v-model="form.meats" id="8e" option="Fish"></checkbox>
      <checkbox v-model="form.meats" id="8f" option="Vegetarian Only"></checkbox>
      <checkbox v-model="form.meats" id="8g" option="Vegan Only"></checkbox>
      {{ form.meats }}
    </div>
    
    
    {{form.meats}}
    
    Vue.component('checkbox')

    Vue.component('checkbox'{
    模板:`
    {{option}}
    `,
    数据(){
    返回{
    checkedProxy:false
    }
    },
    计算:{
    检查:{
    得到(){
    返回此.value
    },
    设置(选项){
    this.checkedProxy=选项
    }
    }
    },
    方法:{
    更新:职能(e){
    this.$emit('input',this.checkedProxy)
    }
    },
    道具:{
    值:null,
    选项:null,
    身份证:{
    类型:字符串,
    必填项:true
    }
    }
    });
    新Vue({
    el:“调查问卷”,
    数据:{
    表格:{
    肉类:[],
    }
    }
    })
    
    我想这就是你想要的

    <div id="questionnaire">
      <check-group :chks="chks" v-model="form.meats"></check-group>
      {{ form.meats }}
    </div>
    
    const groups = {
        '1': {
            tag: 'meats',
            exclusiveGroups: [2]
        },
        '2': {
            tag: 'vegan',
            exclusiveGroups: [1]
        }
    }
    
    const chks = {
        'Chicken': {
            groupIds: [1]
        },
        'Turkey': {
            groupIds: [1]
        },
        'Beef': {
            groupIds: [1]
        },
        'Pork': {
            groupIds: [1]
        },
        'Fish': {
            groupIds: [1]
        },
        'Vegetarian Only': {
            groupIds: [2]
        },
        'Vegan Only': {
            groupIds: [2]
        }
    }
    
    Vue.component('checkbox', {
        template: `
        <div>
            <label>
                <input type="checkbox" ref="chk" :value="val" v-model="value" @change="update($event)">
                {{ txt }}
                <slot></slot>
            </label>
            <input type="checkbox" :checked="value.indexOf(val)<0" @change="reverseSelection($event)">
        </div>
        `,
        data () {
            return {
                val: this.optValue || this.optText,
                txt: this.optText || this.optValue
            }
        },
        methods: {
            update (e) {
                this.$emit('input', this.value, e.target.value, e.target.checked)
            },
            reverseSelection () {
                var e = document.createEvent("MouseEvents");
                e.initEvent("click", true, true);
                this.$refs.chk.dispatchEvent(e);
            }
        },
        props: ['value','optValue','optText']
    });
    
    Vue.component('check-group',{
        template: `
            <div>
                <checkbox v-for="item in chks" :opt-value="item.value" :opt-text="item.text" @input="update" v-model="value"></checkbox>
            </div>
        `,
        props: {
            value: {
                required: true,
                type: Array
            },
            chks: {
                required: true,
                type: Array
            }
        },
        methods: {
            update (val,curVal,checked) {
                if(checked){//only checkbox be checked need to judge mutually-exclusive
                    chks[curVal].groupIds.forEach(id=>{//iterate all group of this checkbox
                        groups[id].exclusiveGroups.forEach(eid=>{//iterate all exclusiveGroups of this group
                            for(let i=0;i<val.length;i++){
                                let p = chks[val[i]].groupIds.indexOf(eid)
                                if(p>=0){//if this checkbox's group in exclusiveGroups then remove this item from val Array
                                    val.splice(p,1)
                                    i--
                                }
                            }
                        })
                    })
                }
                this.$emit('input',val)
            },
        }
    })
    
    new Vue({
        el: "#questionnaire",
        data: {
            chks: Object.keys(chks).map(key=>({value: key,groupIds: chks[key]})),
            form: {
                meats: ['Chicken']
            }
        }
    })
    

    你检查过这个了吗:对2或3没有帮助。我已经猜出来了。此外,我的是一个复选框。很好,但有助于理解它是如何工作的。此外,素食者和素食者不能同时被选中:)chks中的GroupID表示此复选框的组(可以多个)和const groups存储组信息,exclusiveGroups表示哪些组与此组相互排斥只需设置其GroupID和exclusiveGroups这一点。$refs.chk用于获取该复选框的dom引用,和dispatchEvent(e)可以触发复选框的“onclick”事件。就像您单击该复选框并询问有关“v-for”的问题一样,您可以像这样为erery复选框绑定一个“key”:这里需要一个唯一的键,以便vue操作dom元素
    <div id="questionnaire">
      <check-group :chks="chks" v-model="form.meats"></check-group>
      {{ form.meats }}
    </div>
    
    const groups = {
        '1': {
            tag: 'meats',
            exclusiveGroups: [2]
        },
        '2': {
            tag: 'vegan',
            exclusiveGroups: [1]
        }
    }
    
    const chks = {
        'Chicken': {
            groupIds: [1]
        },
        'Turkey': {
            groupIds: [1]
        },
        'Beef': {
            groupIds: [1]
        },
        'Pork': {
            groupIds: [1]
        },
        'Fish': {
            groupIds: [1]
        },
        'Vegetarian Only': {
            groupIds: [2]
        },
        'Vegan Only': {
            groupIds: [2]
        }
    }
    
    Vue.component('checkbox', {
        template: `
        <div>
            <label>
                <input type="checkbox" ref="chk" :value="val" v-model="value" @change="update($event)">
                {{ txt }}
                <slot></slot>
            </label>
            <input type="checkbox" :checked="value.indexOf(val)<0" @change="reverseSelection($event)">
        </div>
        `,
        data () {
            return {
                val: this.optValue || this.optText,
                txt: this.optText || this.optValue
            }
        },
        methods: {
            update (e) {
                this.$emit('input', this.value, e.target.value, e.target.checked)
            },
            reverseSelection () {
                var e = document.createEvent("MouseEvents");
                e.initEvent("click", true, true);
                this.$refs.chk.dispatchEvent(e);
            }
        },
        props: ['value','optValue','optText']
    });
    
    Vue.component('check-group',{
        template: `
            <div>
                <checkbox v-for="item in chks" :opt-value="item.value" :opt-text="item.text" @input="update" v-model="value"></checkbox>
            </div>
        `,
        props: {
            value: {
                required: true,
                type: Array
            },
            chks: {
                required: true,
                type: Array
            }
        },
        methods: {
            update (val,curVal,checked) {
                if(checked){//only checkbox be checked need to judge mutually-exclusive
                    chks[curVal].groupIds.forEach(id=>{//iterate all group of this checkbox
                        groups[id].exclusiveGroups.forEach(eid=>{//iterate all exclusiveGroups of this group
                            for(let i=0;i<val.length;i++){
                                let p = chks[val[i]].groupIds.indexOf(eid)
                                if(p>=0){//if this checkbox's group in exclusiveGroups then remove this item from val Array
                                    val.splice(p,1)
                                    i--
                                }
                            }
                        })
                    })
                }
                this.$emit('input',val)
            },
        }
    })
    
    new Vue({
        el: "#questionnaire",
        data: {
            chks: Object.keys(chks).map(key=>({value: key,groupIds: chks[key]})),
            form: {
                meats: ['Chicken']
            }
        }
    })
    
    const groups = {
        '1': {
            tag: 'meats',
            exclusiveGroups: [2] //means that when the checkbox of this group be checked,the checkbox whose group-index equals 2 where be unchecked
        },
        '2': {
            tag: 'vegan',
            exclusiveGroups: [1,3]
        },
        '3': {
            tag: 'Vegetarian Only',
            exclusiveGroups: [1,2]
        }
    }
    
    const chks = {
        'Chicken': {
            groupIds: [1]
        },
        'Turkey': {
            groupIds: [1]
        },
        'Beef': {
            groupIds: [1]
        },
        'Pork': {
            groupIds: [1]
        },
        'Fish': {
            groupIds: [1]
        },
        'Vegetarian Only': {
            groupIds: [3]
        },
        'Vegan Only': {
            groupIds: [2]
        }
    }