Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Child component to use parent function in vue js

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!

like image 914
Modelesq Avatar asked Feb 24 '17 19:02

Modelesq


People also ask

How do you use the parent function in child components?

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.

How do I pass data from parent to child component in Vue?

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.


1 Answers

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>
like image 198
Peter Avatar answered Oct 04 '22 18:10

Peter