You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过自定义$emit事件更新多复选框绑定的数组类型v-model?

解决方案

问题原因

你之前直接将点击事件对象e通过input事件 emit 给父组件,Vue的v-model默认会将input事件的第一个参数直接赋值给绑定的变量,才会出现fields被替换为PointerEvent对象的问题。自定义组件实现数组型v-model的增删逻辑,需要你自己基于父组件传入的value(v-model绑定值对应的props)处理后,emit完整的新数组即可。

代码修改

1. 修正主组件属性绑定错误

原代码中:name="email"会将email当作变量读取,会触发变量未定义报错,要传字符串的话可以去掉冒号,或者用引号包裹变量值:

<template>
    <div>
        <helper-switch name="email" v-model="fields"></helper-switch>
        <helper-switch name="phone" v-model="fields"></helper-switch>
        <div>
            {{ fields }}
        </div>
    </div>
</template>
<script>
import helperSwitch from './input/HelperSiwtch.vue'
export default {
    components:{
        helperSwitch,
    },
    data() {
        return {
            fields:[]
        }
    }
}
</script>

2. 子组件helper-switch修改

<template>
  <div>
    <label for="c1">Field</label>
    <input type="checkbox" id="c1" v-model="fieldBool" @change="updateFields" />
    <label for="c2">Required</label>
    <input type="checkbox" id="c2" v-model="requiredBool" @change="updateFields" />
  </div>
</template>
<script>
export default {
  methods: {
    updateFields() {
      // 拷贝父组件传入的数组,不直接修改props符合单向数据流
      const newFields = [...this.value]
      // 查找当前name对应的项是否已存在于数组中
      const existIndex = newFields.findIndex(item => item.name === this.name)

      if (this.fieldBool) {
        // 选中Field的情况:更新或新增对应项
        const item = {
          name: this.name,
          required: this.requiredBool
        }
        if (existIndex > -1) {
          newFields.splice(existIndex, 1, item)
        } else {
          newFields.push(item)
        }
      } else {
        // 取消选中Field的情况:删除对应项
        if (existIndex > -1) {
          newFields.splice(existIndex, 1)
        }
      }
      // emit新数组,v-model会自动更新父组件的fields
      this.$emit('input', newFields)
    },
  },
  props: {
    name: String,
    value: Array
  },
  data() {
    return {
      fieldBool: false,
      requiredBool: false,
    };
  },
};
</script>

实现说明

  • 监听两个复选框的change事件而非click事件,更符合复选框状态变更的触发逻辑
  • 子组件不会直接修改父组件传入的value属性,拷贝后修改再emit,符合Vue单向数据流规范
  • 勾选Field复选框时会自动将{name: 传入的name值, required: Required复选框状态}的对象加入数组,取消勾选则移除对应项
  • 修改Required复选框的状态也会同步更新数组中对应项的required属性

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 11:15:06