Vue封装v-text-field引发数据不更新与只读警告问题求助
Vue封装表单组件后数据无法更新&只读警告的解决方法
问题根源
Vue 3遵循单向数据流规则,子组件不能直接修改父组件传递的props——props本质是只读的。你在MyInput.vue中直接用v-model="props.model",相当于试图修改只读的props值,这就触发了「Set operation on key "model" failed: target is readonly.」警告,同时父组件的formData也无法同步更新。
正确的做法是利用Vue的自定义v-model机制:子组件通过触发事件通知父组件修改数据,而非直接操作props。
具体代码修改
1. 调整 MyInput.vue(核心子组件)
将props改为Vue3默认的modelValue,并定义更新事件:
<script setup> const props = defineProps({ modelValue: { type: String, required: true, }, label: { type: String, required: true, }, fieldData: { type: Object, required: true, }, }); // 定义用于更新父组件数据的事件 const emit = defineEmits(['update:modelValue']); </script> <template> <v-text-field :value="props.modelValue" :label="props.label" :error-messages="props.fieldData.$errors.map((e) => e.$message)" @input="(val) => { emit('update:modelValue', val); props.fieldData.$touch(); }" @blur="props.fieldData.$touch" variant="outlined" ></v-text-field> </template>
这里把v-model拆分为:value(绑定父组件传递的初始值)和@input(触发更新事件+触发表单校验),彻底避免直接修改props。
2. 调整 StyledInput.vue(中间组件)
作为嵌套组件,需要透传v-model的props和事件:
<script setup> import MyInput from "./MyInput.vue"; const props = defineProps({ modelValue: { type: String, required: true, }, label: { type: String, required: true, }, fieldData: { type: Object, required: true, }, }); const emit = defineEmits(['update:modelValue']); </script> <template> <MyInput :modelValue="props.modelValue" :label="props.label" :fieldData="props.fieldData" @update:modelValue="emit('update:modelValue', $event)" ></MyInput> </template>
3. 调整 Form.vue 中的组件调用
将原来的:model绑定改为标准的v-model:
<StyledInput v-model="formData.username2" label="Username 2" :fieldData="v$.username2" />
StyledInput2、StyledInput3也按此逻辑调整,确保用v-model绑定表单字段。
效果验证
修改后,子组件会通过emit通知父组件更新formData,既符合Vue的数据流规则,也能正常同步表单输入,同时消除只读警告。
内容的提问来源于stack exchange,提问作者FTW
相关产品推荐
相关产品推荐

