How can I get all input values from dynamic form as a single object with key-values pairs? Where key is input name and value is user input.
I have a custom input component. In app component I dynamically render inputs from array:
<template>
<div>
<form @submit.prevent="submit">
<ul>
<li v-for="input in inputFields" :key="input.label">
<base-input
:placeholder="input.placeholder"
:type="input.type"
:name="input.name"
v-model="userInput[input.name]"
></base-input>
</li>
</ul>
<button type="submit">Console.log input</button>
</form>
</div>
</template>
<script>
import BaseInput from "./components/BaseInput.vue";
export default {
components: { BaseInput },
data() {
return {
inputFields: INPUT_FIELDS,
userInput: {
name: "",
phone: "",
email: "",
location: "",
address: "",
comment: "",
},
};
},
methods: {
submit() {
console.log("userInput:", this.userInput);
},
},
};
</script>
Then in base-input component:
<template>
<input
:type="type"
:name="name"
:placeholder="placeholder"
@input="$emit('update:modelValue', $event.target.value)"
:value="modelValue[name]"
/>
</template>
<script>
export default {
emits: ["update:modelValue"],
props: {
label: {
type: String,
required: false,
},
placeholder: {
type: String,
required: true,
},
type: {
type: String,
required: true,
},
name: {
type: String,
required: false,
},
modelValue: {},
},
};
</script>
Expected behavior: click on submit --> get object like in console:
{
name: "user name",
phone: "1111",
email: "[email protected]",
location: "World",
address: "",
comment: "no",
},
Actual behavior: I can only type 1 letter in a field and no more.
Here's a codesandbox: https://codesandbox.io/s/optimistic-alex-dzw0mp?file=/src/App.vue
CodePudding user response:
You were close. You need to remove [name]
from the end of :value="modelValue[name]"
in the base-input component. Since you are already scoping to name
in the parent component it is wrong to also look for a [name]
prop on the value of modelValue within your child component.
See it working here: https://codesandbox.io/s/unruffled-cohen-bivefc?file=/src/components/BaseInput.vue
Your component template should be:
<input
:type="type"
:name="name"
:placeholder="placeholder"
@input="$emit('update:modelValue', $event.target.value)"
:value="modelValue"
/>