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

I have the following structure of Vue ponents:<TopParent> <!-- listen for EventProducer'

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.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744708830a4589217.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信