Nuxt 3:父元素未从子组件接收 v-model 输入

问题描述 投票:0回答:1

我正在开发一个 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 来绑定它们。有人可以帮助确定为什么父级不使用子级的输入值进行更新吗?

javascript vue.js nuxt.js nuxtjs3 v-model
1个回答
0
投票

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>
© www.soinside.com 2019 - 2024. All rights reserved.