Vue3 Option API问题:父组件无法接收子组件v-model输入值
Nuxt3联系表单:父组件无法接收子组件输入值的解决方案
问题
在Nuxt3项目中,使用自定义输入组件UtilityMainInput与父组件通过v-model绑定表单字段后,提交时父组件的form对象所有值始终为null,无法获取用户输入内容。
原因
Vue3(Nuxt3基于Vue3)对自定义组件的v-model实现做了调整:
- 不再默认使用
valueprop和input事件,而是改用modelValueprop和update:modelValue事件 - 你的子组件仍沿用Vue2的
v-model实现方式,导致父组件无法接收到子组件的输入更新
修复步骤
1. 修改子组件UtilityMainInput适配Vue3规范
将原有的value prop替换为modelValue,并把input事件改为update:modelValue:
修复后的子组件代码
<template> <div class="normal-form"> <label :for="name" class="label"> {{ name }} </label> <!-- text input --> <input v-if="controlType === 'input' && inputType ==='text'" type="text" maxlength="50" :name="name" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)"> <!-- email input --> <input v-if="controlType === 'input' && inputType ==='email'" type="email" :name="name" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)"> <!-- textarea input --> <div class="textarea" v-if="controlType === 'textarea'"> <textarea :name="name" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)"> </textarea> </div> </div> </template> <script> export default { props: { name: { type: String, required: true }, placeholder: { type: String, required: false, default: "text goes here" }, inputType: { type: String, required: false, default: "text" }, controlType: { type: String, required: false, default: 'input' }, modelValue: { // 替换原有的value prop type: String, default: '' } }, } </script>
2. (可选)子组件改用<script setup>语法(更贴合Nuxt3)
如果想使用Nuxt3推荐的<script setup>,子组件可以改成这样:
<template> <div class="normal-form"> <label :for="name" class="label"> {{ name }} </label> <!-- text input --> <input v-if="controlType === 'input' && inputType ==='text'" type="text" maxlength="50" :name="name" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)"> <!-- email input --> <input v-if="controlType === 'input' && inputType ==='email'" type="email" :name="name" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)"> <!-- textarea input --> <div class="textarea" v-if="controlType === 'textarea'"> <textarea :name="name" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)"> </textarea> </div> </div> </template> <script setup> const props = defineProps({ name: { type: String, required: true }, placeholder: { type: String, required: false, default: "text goes here" }, inputType: { type: String, required: false, default: "text" }, controlType: { type: String, required: false, default: 'input' }, modelValue: { type: String, default: '' } }) </script>
3. 父组件修正ref一致性问题
父组件中模板的表单ref为formm,但脚本里定义的是formElement,可以修正为统一命名:
<script setup> import { ref } from 'vue'; const formm = ref(null); // 修正为和模板ref一致 const errorMessage = ref(null); const form = ref({ name: null, subject: null, email: null, message: null }); // ... 其余submitForm和formSubmit函数保持不变 </script>
父组件的v-model绑定无需修改,Vue3会自动映射到子组件的modelValue和update:modelValue事件。
验证
修改完成后,输入表单内容并提交,父组件的form对象会正确获取到子组件的输入值,提交逻辑可以正常执行。
内容的提问来源于stack exchange,提问作者Opeyemi Odedeyi
相关产品推荐
相关产品推荐

