VueJs Tree recursive elements emits to parent

Viewed 9092
3 Answers

Here's another solution if you don't want to create multiple Vue instances. I use this in my single file recursive components.

It uses the v-on directive (I'm using the @ shorthand).

In your recursive component <template>:

<YourComponent @bus="bus"></YourComponent>

In the recursive component methods:

methods: {
    bus: function (data) {
        this.$emit('bus', data)
    }
}

To kick it off, you emit an event in a child:

this.$emit('bus', {data1: 'somedata', data2: 'somedata'})

That data will be transmitted all the way up the chain, and then you receive that event in the page that called your recursive component:

methods: {
    bus (data) {
        // do something with the data
    }
}

Here's a fiddle showing it in action on the Vue.JS tree example. Right-click on an element, and it will output that model in the console:

https://jsfiddle.net/AlanGrainger/r6kxxoa0/

Use v-on="$listeners"

I'll let you into a little secret. The Vue $listeners property (which is documented as being there to pass events down to children), also passes child events to parents!

https://v2.vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components

Here is a pseudo-code example (shorthand for illustrative purposes):

<ancestor-component @messageForAncestor="displayMessage">
  ...
  <parent-component v-on="$listeners">
    ...
    <child-component @click="$emit('messageForAncestor')">

In the display above the child component would pass up an event. The parent would typically be able to listen for the messageForAncestor event and that's where it would need to stop, but. Putting v-on="$listeners" on the parent actually says please pass it on.

Warn: That was probably a bad idea

This is probably a very bad idea though. A better idea would be to simply ask the middle component (the parent) to pass it on...

<!-- better idea (listen for message and pass on message) --> 
<parent-component @message="$emit('message', $event)">

Related