Vue中如何将v-model透传给孙组件并实现双向绑定?
组件嵌套中v-model的传递与同步问题
问题场景
组件层级为 Form.vue -> FormTextInput.vue -> TextInput.vue,需要在Form.vue中通过v-model绑定数据,实现数据从顶层到底层输入组件的传递,同时将输入组件的变更同步回顶层。
最初的实现代码
Form.vue
<FormTextInput type="text" label="First name" identifier="first_name" v-model="form.first_name" />
FormTextInput.vue
defineProps({ modelValue: { type: String, required: true, }, }); defineEmits(['update:modelValue']); <TextInput type="text" :modelValue="modelValue" @update:modelValue="$emit('update:modelValue', $event.target.value)" > </TextInput>
TextInput.vue
defineProps({ modelValue: { type: String, required: true, }, }); defineEmits(['update:modelValue']); <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
出现的错误
TypeError: Cannot read properties of undefined (reading 'value') at _createVNode.onUpdate:modelValue._cache.<computed>._cache.<computed> (FormTextInput.vue:42:78)
修改后的正确代码(FormTextInput.vue部分)
将事件监听代码修改为:
@update:modelValue="$emit('update:modelValue', $event)"
问题解释
你的理解完全正确:TextInput.vue在触发update:modelValue事件时,已经把输入框的value值作为事件参数传递了,所以FormTextInput.vue接收到的$event就是这个直接的字符串值,而不是原生的input事件对象,自然不存在target.value属性,这就是报错的根源。
透传组件的合理性
把FormTextInput.vue作为透传组件处理这个场景是完全正确的做法。这类组件通常承担业务封装的角色(比如统一添加label、校验提示、样式等),不需要自己处理数据逻辑,只需要将modelValue属性和update:modelValue事件透传给底层输入组件即可。
甚至可以用Vue的v-model语法糖进一步简化代码,直接在FormTextInput.vue中写:
<TextInput v-model="modelValue" />
Vue会自动帮你完成modelValue属性的绑定和update:modelValue事件的监听与转发,代码会更简洁。
内容的提问来源于stack exchange,提问作者Torben
相关产品推荐
相关产品推荐

