В моем приложении Nuxt3 я пытаюсь передать значение, введенное в поле ввода электронной почты, из дочернего компонента (SignForm.vue) в родительский компонент (signup.vue), чтобы я мог использовать его для регистрации нового пользователя.
Signup.vue
<script setup>
const props = {
fields: [
"email",
"password",
"confirm",
],
header: "Register a new account",
button: [
{
text: "Sign Up",
color: "green-500",
}
]
};
const email = ref('');
const password = ref('');
const confirm = ref('');
function signUp(email) {
console.info(email)
}
</script>
<template>
<SignForm :props = "props" @method = "signUp"/>
</template>
SignForm.vue
<script setup>
const email = ref('');
const password = ref('');
const { props } = defineProps(['props']);
</script>
<template>
<div class = "container">
<form class = "flex flex-col items-center gap-2">
<p class = "text-2xl pb-2">{{ props.header }}</p>
<input v-for = "(pf, index) in props.fields" :key = "index"
:type = "[`${pf}` === 'confirm' ? 'password' : `${pf}`]"
:placeholder = "`${pf}`"
:v-model = "`${pf}`"
class = "bg-gray-300 rounded p-2 w-2/5"
>
<button type = "submit" v-for = "(btn, index) in props.button" :key = "index"
class = "p-2 text-white rounded w-2/5 text-sm opacity-85 hover:font-bold hover:opacity-100"
:class = "`bg-${ btn.color }`"
@click.prevent = "$emit('method', email)"
>
<span>{{ btn.text }}</span>
</button>
</form>
</div>
</template>
Значение электронной почты по-прежнему не выдается должным образом — оно либо пустое, либо undefined
ОБНОВЛЕНО: https://play.vuejs.org/





Вот быстрое воспроизведение пример того, как это должно работать.
Вы можете использовать инструменты разработчика Vue для дальнейшей проверки и попытаться выяснить, что излучается дочерним компонентом. Кроме того, я думаю, что удаление некоторых v-for может облегчить отладку.
PS: не используйте индекс в качестве :ключа.
На самом деле я думаю, что ваша проблема в том, что вы ожидаете получить email от дочернего элемента, но у вас есть локальный email от родителя. Итак, вы, вероятно, получаете $event up, как и ожидалось, но вы console.info загружаете локальный, который пуст.
Пожалуйста попробуйте
<SignForm :props = "props" @method = "console.info($event)" />
В этом случае $event должно быть электронное письмо ref, отправленное ребенком.
PS2: возможно, рассмотрите возможность отсутствия двух одинаковых имен email ссылок с разницей в 1 уровень глубины для вашей собственной отладки и простоты использования.
Дополнительную информацию о $event можно найти в документации.
Я прикрепил ссылку на свой play.vuejs.org в исходном вопросе.
Проблема с приведенным выше кодом заключается в том, что вы пытаетесь связать строковое значение вместо реактивного значения, поэтому в email не отображается никаких изменений по сравнению с SignForm.vue.
Простым решением этой проблемы было бы создание реактивного объекта с хранилищем ключа: имени поля и значения: входного значения. Это можно сделать, используя обе функции ref или reactive.
РЕШЕНИЕ
<script setup>
import { ref } from 'vue'
const form = ref({
email: '',
password: '',
});
const { props } = defineProps(['props']);
</script>
<template>
<div>
<form>
<p>{{ props.header }}</p>
<input v-for = "pf in props.fields"
:type = "`${pf}`"
:placeholder = "`${pf}`"
v-model = "form[pf]"
>
<button type = "submit" v-for = "btn in props.button"
@click.prevent = "$emit('method', form.email)"
>
{{ btn.text }}
</button>
</form>
</div>
</template>
Это не динамично, но определенно работает, да.
form ссылка может работать правильно даже с таким пустым объектом const form= ref<Record<string, string>>({});
Спасибо @kissu! Я думаю, что проблема в директиве v-model внутри первого цикла v-for, она связывает правильное значение (в данном случае адрес электронной почты), но каким-то образом не подхватывается событием @click. Когда я меняю его на нединамическое значение, например v-model = "email", оно работает как положено.