Vue3自定义输入组件双向绑定失效,提交时数据为undefined求助
问题分析与修复
核心问题
- Vue3 中
v-model的默认规则已更新:- 父组件用
v-model时,默认传递的 prop 是modelValue,而非 Vue2 的value - 子组件需触发
update:modelValue事件同步数据,而非input事件
- 父组件用
- Form.vue 里同时绑定
:value="id"和v-model="id",造成数据绑定冲突,打乱了 v-model 的正常逻辑
修复步骤
1. 调整 CustomInput.vue(适配 Vue3 规范)
<template> <input :type="type" :value="modelValue" @input="onChange" :placeholder="placeholder" /> </template> <script lang="ts"> import { defineComponent } from "vue"; export default defineComponent({ name: "custom-input", props: { type: String, // 替换为 Vue3 v-model 默认的 prop 名 modelValue: String, // 补上父组件传递但未接收的 placeholder 属性 placeholder: String }, methods: { onChange(event: Event) { const target = event.target as HTMLInputElement; // 触发 Vue3 对应的更新事件 this.$emit("update:modelValue", target.value); }, }, }); </script>
2. 修改 Form.vue(移除冗余绑定)
<template> <form @submit.prevent="onsubmit"> <h2>Bucket Login</h2> <!-- 删掉重复的 :value 绑定,v-model 已包含双向绑定逻辑 --> <CustomInput type="text" v-model="id" placeholder="ID" /> <CustomInput type="password" v-model="password" placeholder="PASSWORD" /> <CustomButton>Login</CustomButton> <p @click="moveJoin">Join</p> </form> </template> <script lang="ts"> import { defineComponent } from "vue"; import CustomButton from "./CustomButton.vue"; import CustomInput from "./CustomInput.vue"; export default defineComponent({ name: "login-form", components: { CustomButton, CustomInput, }, data: () => ({ id: "", password: "", }), methods: { onsubmit() { console.log(this.id); // 现在会正常输出输入值 }, moveJoin() { this.$router.push("/join"); }, }, }); </script>
补充说明
如果需要自定义 v-model 的 prop 和事件名,可在子组件中配置model选项:
export default defineComponent({ model: { prop: "value", event: "input" }, // ...其余代码 })
但更推荐遵循 Vue3 官方规范使用modelValue和update:modelValue,避免不必要的兼容性问题。
内容的提问来源于stack exchange,提问作者고윤태
相关产品推荐
相关产品推荐

