我正在开发一个 Nuxt 3 项目,并面临联系表单的问题,其中父元素似乎没有从子组件接收输入值。这是我的代码的细分:
父组件:
<script setup>
import { ref } from 'vue';
const formElement = ref(null);
const errorMessage = ref(null);
const form = ref({
name: null,
subject: null,
email: null,
message: null
});
const submitForm = () => {
if (!form.value.name || !form.value.subject || !form.value.message) {
console.log(form.value);
errorMessage.value = "please make sure your 'fullname', 'subject', and 'message' fields are filled";
} else if (!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(form.value.email)) {
errorMessage.value = "please fill in a valid 'email'";
} else if (form.value.message.length < 3) {
errorMessage.value = "please add some more context to the 'message'";
} else {
console.log("button clicked");
console.log(form.value);
formSubmit();
}
};
const formSubmit = () => {
const formElement = document.querySelector('form');
console.log(formElement);
// formElement.submit();
};
</script>
<template>
<form action="https://formsubmit.co/[email protected]" method="POST" ref="formm">
<UtilityMainInput name="Name" placeholder="Full Name" inputType="text" controlType="input" v-model="form.name"/>
<UtilityMainInput name="Subject" placeholder="Subject" inputType="text" controlType="input" v-model="form.subject"/>
<UtilityMainInput name="Email" placeholder="Email Address" inputType="email" controlType="input" v-model="form.email"/>
<UtilityMainInput name="Message" placeholder="Tell us anything" inputType="textarea" controlType="textarea" v-model="form.message"/>
<div class="empty-height"></div>
<UtilityButton type="btn" size="medium" :onClick="submitForm">Send Message</UtilityButton>
</form>
</template>
子组件(UtilityMainInput):
<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="value"
@input="$emit('input', $event.target.value) ">
<!-- email input -->
<input
v-if="controlType === 'input' && inputType ==='email'"
type="email"
:name="name"
:value="value"
@input="$emit('input', $event.target.value) ">
<!-- textarea input -->
<div class="textarea" v-if="controlType === 'textarea'">
<textarea
:name="name"
:value="value"
@input="$emit('input', $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'
},
value: {
type: String,
default: ''
}
},
}
</script>
当我填写表单并单击“提交”时,父组件数据属性中的所有值都为 null,即使我已使用 v-model 来绑定它们。有人可以帮助确定为什么父级不使用子级的输入值进行更新吗?
Vue 3 中有一个重大更改,您应该在 Option api 中遵循。有关更多信息,请参阅官方文档。
Vue 2 版本:
<input
:value="searchText"
@input="searchText = $event.target.value"
/>
Vue 3 版本(Option api 和 Composition api):
<CustomInput
:model-value="searchText"
@update:model-value="newValue => searchText = newValue"
/>
文件的更新代码如下:如果需要,请在 Vue Playground 中检查它
<script setup>
import { ref } from 'vue';
import UtilityMainInput from './UtilityMainInput.vue';
const formElement = ref(null);
const errorMessage = ref(null);
const form = ref({
name: null,
subject: null,
email: null,
message: null
});
const submitForm = () => {
if (!form.value.name || !form.value.subject || !form.value.message) {
console.log(form.value);
errorMessage.value = "please make sure your 'fullname', 'subject', and 'message' fields are filled";
} else if (!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(form.value.email)) {
errorMessage.value = "please fill in a valid 'email'";
} else if (form.value.message.length < 3) {
errorMessage.value = "please add some more context to the 'message'";
} else {
console.log("button clicked");
console.log(form.value);
formSubmit();
}
};
const formSubmit = () => {
const formElement = document.querySelector('form');
console.log(formElement);
// formElement.submit();
};
function test(e) {
console.log(e)
}
</script>
<template>
<form action="https://formsubmit.co/[email protected]" method="POST" ref="formm">
<UtilityMainInput name="Name" placeholder="Full Name" inputType="text" controlType="input" v-model="form.name" />
<UtilityMainInput name="Subject" placeholder="Subject" inputType="text" controlType="input" v-model="form.subject" />
<UtilityMainInput name="Email" placeholder="Email Address" inputType="email" controlType="input"
v-model="form.email" />
<UtilityMainInput name="Message" placeholder="Tell us anything" inputType="textarea" controlType="textarea"
v-model="form.message" />
<div class="empty-height"></div>
<button @click="submitForm">Send Message</button>
</form>
</template>
<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: {
type: String,
default: ''
}
}
}
</script>