具有多个复选框和一个 v 模型的组件

Jor*_*wal 0 vue.js vue-component

我正在为我的应用程序构建“基本”组件,主要用于表单管理。到目前为止,我已经创建了一个自定义 inputtextareaselectradio。但是,所有这些组件一次只有“一个”值。

对于无线电和复选框,我的组件一次构建多个无线电/复选框,所有这些都附加到同一个 v-model。但是,我的复选框组件没有按预期工作。它没有将“所有选中的复选框”存储在 v-model 的数组中,而是只注册最后一个点击的 :(

如何通过从数组中添加/删除元素来覆盖“更改”事件,以便相应地更新附加模型?

这是我的复选框组件代码:

/**
 * @description Component used to display a group of checkboxes
 * @author Jordan Kowal
 * @date 2019-11-30
 * @param name String, name attribute
 * @param alignment String, defines item alignment and should be "centered", "left", or "right"
 * @param block Boolean, whether items are displayed as "block" or "inline-block"
 * @param entries Array, list of objects with the following keys: label, value, active
 * @param errors Array, list of error messages
*/
Vue.component("checkbox-group", {
    props: {
        name: String,
        alignment: String,
        block: Boolean,
        entries: Array,
        errors: Array,
    },
    template:
        "<div class='field'>\
            <p class='help is-danger' v-for='message in errors'>\
                @{message}\
            </p>\
            <div class='control' :class='\"has-text-\" + alignment'>\
                <template v-for='entry in entries'>\
                    <label class='checkbox'>\
                        <input\
                            type='checkbox'\
                            :name='name'\
                            :checked='entry.active'\
                            :value='entry.value'\
                            @change='$emit(\"input\", $event.target.value)'\
                        />\
                        @{entry.label}\
                    </label>\
                    <br v-if='block'>\
                </template>\
            </div>\
        </div>",
});
Run Code Online (Sandbox Code Playgroud)

使用示例:

<checkbox-group
    name="id"
    alignment="centered"
    :block="true"
    v-model="languageForm.fields.languages"
    :entries="languageForm.entries.languages"
    :errors="languageForm.errors.languages"
></checkbox-group>
Run Code Online (Sandbox Code Playgroud)

编辑:

Michal Levý提供的解决方案运行良好

Mic*_*evý 5

看看v-model自定义组件是做什么的

<mycomponent v-model="data" />
Run Code Online (Sandbox Code Playgroud)

<mycomponent 
  v-bind:value="data"
  v-on:input="data= $event" />
Run Code Online (Sandbox Code Playgroud)

因此,如果您$emit("input", $event.target.value)在组件内部进行操作,无论$event.target.value是什么,它都会替换您的模型。但是您需要一个“输入”事件,以便v-model您的组件工作。value发出的格式必须与您收到的模型格式相同。

最重要的是,拥有模型并同时提供支持有entries.active什么意义?这是明显的两面性。传递的模型应该只是决定是否选中复选框的东西....

像这样做:

<mycomponent v-model="data" />
Run Code Online (Sandbox Code Playgroud)

变化:

  1. 添加了valueprop - 它由 Vue 设置v-model为组件属性内的值
  2. 引入model数据 - 变量保存复选框的当前状态。在乞讨时,它是从v-model
  3. 删除,:checked=...因为它是口是心非。复选框的选中状态由模型驱动
  4. 添加观察者 - 每次更改组件内的模型时(通过v-model复选框),发出一个事件,以便更新父模型

工作示例