最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue 3: How to forward all emitted events to a parent component? - Stack Overflow

programmeradmin1浏览0评论

I have the following structure of Vue ponents:

<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> ponent and listen to the event in <TopParent> ponent?

How can I tell all the <Child_1>...<Child_N> ponents 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.

I have the following structure of Vue ponents:

<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> ponent and listen to the event in <TopParent> ponent?

How can I tell all the <Child_1>...<Child_N> ponents 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.

Share Improve this question asked Mar 22, 2023 at 12:08 eXceptioneXception 2,3413 gold badges19 silver badges35 bronze badges 5
  • 1 Use Provide / Inject vuejs/guide/ponents/provide-inject.html – Bin Rohan Commented Mar 22, 2023 at 12:22
  • @BinRohan Correct me, but provide/inject pass values from parent to child, not the way around (which is the case). Or I'm wrong? – eXception Commented Mar 22, 2023 at 12:44
  • You can inject an event bus or an object that needs to be changed, depending on what's foo is for – Estus Flask Commented Mar 22, 2023 at 13:59
  • 2 This question has some good ideas for acplishing what you want – yoduh Commented Mar 22, 2023 at 14:01
  • Like @yoduh said - use an event bus. Every ponent can emit events to the bus and every ponent can subscribe to the bus. If the ponent does not emit events to the bus but to itself - you will have to explicitly listen for the events that are interesting to you in the immediate parent of the ponent in question, and then re-emit those events to the event bus so that every other interested ponent can receive these events. – IVO GELOV Commented Mar 22, 2023 at 16:52
Add a ment  | 

2 Answers 2

Reset to default 3

there are a couple of ways to pass your data to child/parent ponent. 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)
// position file 
import { ref } from 'vue'

const someString = ref<string>('')

export const useComposition = () => {
  return {
    someString,
  }
}
// usage 
import { useComposition } from 'path/to/file'
const { someString } = useComposition()

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 ponent:

import { provide } from 'vue';

...
function activateOnEvent() {
  //...
}

provide('parentFn', activateOnEvent); //key, value

Inside the EventProducer ponent:

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 ponent.

发布评论

评论列表(0)

  1. 暂无评论