I have a method initialized within the parent component called setMessage()
and I'd like to be able to call it within the child component.
main.js
const messageBoard = new Vue({
el: '#message-board',
render: h => h(App),
})
App (App.vue (parent))..
export default {
data() {
return { messages: state }
},
methods: {
setMessage(message) {
console.log(message);
}
},
template: `
<div>
<child-component></child-component>
</div>
`,
}
child
const child = Vue.extend({
mounted() {
// attempting to use this function from the parent
this.$dispatch('setMessage', 'HEY THIS IS MY MESSAGE!');
}
});
Vue.component('child-component', child);
Right now I'm getting this.$dispatch is not a function
error message. What am I doing wrong? How can I make use of parent functions in various child components? I've also tried $emit
, it doesn't throw an error & it doesn't hit the function.
Thank you for your help in advance!
To call a parent's function from a child component, pass the function reference to the child component as a prop. Then you can call that parent's function from the child component like props. parentMethodName(). In the example code, we create a parent component named Parent.
The way it works is that you define your data on the parent component and give it a value, then you go to the child component that needs that data and pass the value to a prop attribute so the data becomes a property in the child component. You can use the root component (App.
You have a couple options.
Option 1 - referencing $parent from child
The simplest is to use this.$parent
from your child component. Something like this:
const Child = Vue.extend({
mounted() {
this.$parent.setMessage("child component mounted");
}
})
Option 2 - emitting an event and handling in parent
But that strongly couples the child to its parent. To fix this, you could $emit
an event in the child and have the parent handle it. Like this:
const ChildComponent = Vue.extend({
mounted() {
this.$emit("message", "child component mounted (emitted)");
}
})
// in the parent component template
<child-component @message="setMessage"></child-component>
Option 3 - central event bus
One last option, if your components don't have a direct parent-child relationship, is to use a separate Vue instance as a central event bus as described in the Guide. It would look something like this:
const bus = new Vue({});
const ChildComponent = Vue.extend({
mounted() {
bus.$emit("message-bus", "child component mounted (on the bus)");
}
})
const app = new Vue({
...
methods: {
setMessage(message) {
console.log(message);
}
},
created() {
bus.$on('message-bus', this.setMessage)
},
destroyed() {
bus.$off('message-bus', this.setMessage)
}
});
Update (Option 2a) - passing setMessage as a prop
To follow up on your comment, here's how it might work to pass setMessage
to the child component as a prop:
const ChildComponent = Vue.extend({
props: ["messageHandler"],
mounted() {
this.messageHandler('from message handler');
}
})
// parent template (note the naming of the prop)
<child-component :message-handler="setMessage"></child-component>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With