Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS - trigger child function

I'm new to using vuejs (2.0). I'm trying to get this functionality down:

  • Click a button
  • Trigger function in child component
  • Increment number in child's data

This is what I currently have

HTML:

<div id="root">
    <cart @addtocart="add()"></cart>
    <button @click="$emit('addtocart')">Add to Cart</button>
</div>

JS:

Vue.component('cart', {
  template: `<span>{{ items }}</span>`,
  data() {
    return {
      items: 0
    }
  },
  methods: {
    add() {
      alert('add');
    }
  }
});


new Vue({
  el: '#root',
  components: ['cart'],
});

Any help would be GREATLY appreciated. Thanks everyone!

like image 636
Grant Vinson Avatar asked Jan 25 '17 19:01

Grant Vinson


People also ask

What is emit in VUE JS?

Vue $emit is a function that lets us emit, or send, custom events from a child component to its parent. In a standard Vue flow, it is the best way to trigger certain events.

How do I call a method of another component in Vuejs?

Just add a $on function to the $root instance and call form any other component accessing the $root and calling $emit function. Save this answer.


1 Answers

You could use a centralized hub to emit events to (as suggested in the docs https://vuejs.org/v2/guide/migration.html#dispatch-and-broadcast-replaced), then listen and react to those events inside your child components. Here's a quick update to your code that does that:

var eventHub = new Vue();

Vue.component('cart', {
  template: `<span>{{ items }}</span>`,
  data() {
    return {
      items: 0
    }
  },
  created() {
    eventHub.$on('add-item', this.add)
  },
  methods: {
    add() {
      alert('add');
      this.items++;
    }
  }
});


new Vue({
  el: '#root',
  components: ['cart'],
  methods: {
    addToCart() {
        eventHub.$emit('add-item')
    }
  }
});

I just started using vue myself so I may be wrong but as far as I know, having a child component depend on a specific parent is a bad idea as it forces the child component to be "coupled" to that parent to function and makes it not portable. Emitting events from a child component back up is fine though since that would just be the component letting anyone listening in know that something happened. I guess you could access the parent and the events it has emitted directly by using this.$parent.$on('add-item', this.method) but that looks hackish to me. Maybe if your root and child component will always be tightly coupled this way, this.$parent would be fine. The "instatiating a new vue instance" example above is probably just another way to do this without making tying your child component up to a parent component since Vue instances implement the event system (thus exposing $emit, $on methods)

like image 138
georaldc Avatar answered Oct 01 '22 21:10

georaldc