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

Vue 3实现向checkedVessels数组添加多值及自定义Input组件适配

自定义Checkbox组件无法绑定数组v-model问题

尝试用自定义Input组件实现多选框绑定数组checkedVessels时失败,但替换为原生<input>元素功能正常。需要修改自定义组件使其支持数组v-model,实现Vue官方文档中的多选框数组绑定效果。

现有代码

父组件模板

<tr v-for="vessel in vessels.data" :key="vessel.id">
    <Input type="checkbox" v-model="checkedVessels" :value="vessel.id" />
</tr>

父组件脚本

data () {
    return {
        term: '',
        importing: false,
        exporting: false,
        form: this.$inertia.form({
            file: null
        }),
        checkedVessels: []
    }
},

自定义Input组件(原代码)

<template>
<input class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" ref="input">
</template>

<script>
export default {
    props: ['modelValue'],

    emits: ['update:modelValue'],

    methods: {
        focus() {
            this.$refs.input.focus()
        }
    }
}
</script>

问题原因

原生checkbox的v-model绑定数组时,Vue会自动处理选中时添加值、取消时移除值的逻辑,但当前自定义组件只适配了普通输入框的value和input事件逻辑,没有处理checkbox的checked状态和change事件,也没针对数组类型的modelValue做适配。

修改方案

更新自定义Input组件,适配checkbox类型的特殊逻辑:

  1. 新增type和value props,接收父组件传入的类型和选项值
  2. 针对checkbox类型,绑定checked属性而非value,通过modelValue.includes(value)判断是否选中
  3. 监听change事件(checkbox状态变化触发change而非input),根据选中状态更新父组件的数组
  4. 保留普通输入框的原有逻辑

修改后的Input.vue

<template>
  <input 
    class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm"
    :type="type"
    :value="type !== 'checkbox' ? modelValue : value"
    :checked="type === 'checkbox' ? modelValue.includes(value) : false"
    @input="handleInput"
    @change="handleChange"
    ref="input"
  >
</template>

<script>
export default {
  props: {
    modelValue: {
      type: [String, Number, Array],
      default: ''
    },
    type: {
      type: String,
      default: 'text'
    },
    value: {
      type: [String, Number],
      default: ''
    }
  },

  emits: ['update:modelValue'],

  methods: {
    focus() {
      this.$refs.input.focus()
    },
    handleInput(e) {
      if (this.type !== 'checkbox') {
        this.$emit('update:modelValue', e.target.value)
      }
    },
    handleChange(e) {
      if (this.type === 'checkbox') {
        const isChecked = e.target.checked
        let newModelValue
        if (isChecked) {
          // 避免重复添加
          newModelValue = [...new Set([...this.modelValue, this.value])]
        } else {
          // 移除对应值
          newModelValue = this.modelValue.filter(item => item !== this.value)
        }
        this.$emit('update:modelValue', newModelValue)
      }
    }
  }
}
</script>

修改后,父组件无需调整代码,即可实现和原生checkbox一致的数组v-model绑定效果:选中时将vessel.id加入checkedVessels数组,取消时移除对应值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:50:44