skip to Main Content

I have the following structure of Vue components:

<TopParent> <!-- listen for EventProducer's events here -->
  <Child_1>
    <Child_2>
      <Child_3>
        ... 
        <Child_N>
          <EventProducer /> <!-- emit events here --> 
        </Child_N>

      </Child_3>
    </Child_2>
  </Child_1>
</TopParent>

Question

I want to emit an event in <EventProducer> component and listen to the event in <TopParent> component?

How can I tell all the <Child_1>...<Child_N> components to just forward event to the parent?

P.S. I don’t want to specify the exact names of the event, just to forward all of the events.


A stupid solution

In a very primitive way I could do it like this. But it very verbose, especially when there are more than 1 event:

<TopParent @foo="doTheJob()">
  <Child_1  @foo="emit('foo')">
    <Child_2  @foo="emit('foo')">
      <Child_3  @foo="emit('foo')">
        ... 
        <Child_N @foo="emit('foo')">
          <EventProducer @click="emit('foo')"/> 
        </Child_N>

      </Child_3>
    </Child_2>
  </Child_1>
</TopParent>

I believe there is a better way than this.

2

Answers


  1. Chosen as BEST ANSWER

    This can be achieved with provide/inject feature.

    The idea is to provide a kind of "callback function" from TopParent to EventProducer.

    Inside the TopParent component:

    import { provide } from 'vue';
    
    ...
    function activateOnEvent() {
      //...
    }
    
    provide('parentFn', activateOnEvent); //key, value
    

    Inside the EventProducer component:

    import { inject } from 'vue';
    ...
    const parentFn = inject('parentFn');
    ...
    <button @click="parentFn()">Click</button>
    

    So, on your event you can directly call a function from the TopParent component.


  2. there are a couple of ways to pass your data to child/parent component. Before implementation pay attention to what you need exactly

    1. Provide / Inject (can be global)
    2. store vuex; pinia (can be global)
    3. emit/props (just parent/child)
    4. useComposition (can be global)
    // composition file 
    import { ref } from 'vue'
    
    const someString = ref<string>('')
    
    export const useComposition = () => {
      return {
        someString,
      }
    }
    
    // usage 
    import { useComposition } from 'path/to/file'
    const { someString } = useComposition()
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search