问题
Here is my use case:
My main page have several sub-components that collect different input from user, finally I want to submit the whole page with all inputs collected. Therefore I want to retrieve the data from sub-component
One option is to use store
, but my sub-components are super simple, just some forms, store
seems too heavy...
Another option is that I can modify prop
, although I know this is bad practice, but this approach looks just perfect....
Is it ok to modify prop
if my logic is simple?(just collect inputs from user)Or I have to go for Vuex
and store
回答1:
Expanding on excellent answers from Ifaruki and Andres Foronda, another, related option is the use of the sync
modifier on the child component's prop.
Suppose the child component has a prop named name
. In the parent component, you can use the sync
modifier like this:
<Child :name.sync="childName"></Child>
Then, in the child component, when the value of the name
prop should be updated, don't update it directly. Instead, emit an event that follows the naming convention for sync-able props, which is update:nameOfProp
. So in our example, the child component would do this:
this.$emit('update:name', newName);
The benefit of the sync modifier is that we don't have to write an event handler function in the parent component--Vue does that for us and updates the variable that is bound to the prop automatically.
You can read more details about the sync
modifier in the official docs.
回答2:
Retreiving data from sub component works with $emit
here an exapmle:
//parent copmonent
<template>
<div>
<child @someEvent="someMethod"></child>
</div>
</template>
import child from "path/"
<script>
export default {
components: {
child
},
methods: {
someMethod(data){
console.log(data);
}
}
}
</script>
Child component
<template>
<div>
<button @click="sendEvent">send</button>
</div>
</template>
<script>
export default {
methods: {
sendEvent(){
this.$emit("someEvent", "working");
}
}
}
</script>
$emit
takes 2 arguments. The first is the event name and the second one is the data that you send.
The parent just needs to listen with @
for that event that being fired.
回答3:
you can listen an event from child an update the parent data property
//parent component
<div>
<input-name @updateName="eventToUpdateName" /> <!--child component-->
</div>
...
data: () => ({ nameFromChild: '' )},
methods: {
eventToUpdateName(value) {
this.nameFromChild = value; // Update from child value emitted
}
}
...
And in the child component
// Child component
<input v-model="name" />
...
data: () => ({ name: '' }),
// watch for changes in the name property and emit an event, and pass the value to the parent
watch: { name() { this.$emit('updateName', this.name } }
...
Also, You can use a v-model directive and emit 'input' event from child.
//parent component
<div>
<input-name v-model="nameFromChild" /> <!--child component-->
</div>
...
data: () => ({ nameFromChild: '' )}
...
Now in the child component you can have
// Child component
<div>
<input v-model="name" />
</div>
data: () => ({ name: '' }),
props: { value: { type: String, default: '' },
created() { this.name = this.value }, // You can receive a default value
watch: { name() { this.$emit('input', this.name } }
...
来源:https://stackoverflow.com/questions/61473174/vue-how-to-get-value-from-sub-component