Anna Jsk
Anna Jsk

Reputation: 25

how to manage v-on/@ in dynamic components <component :is="currentPage" etc. ></component> structure in vue3 options api

I am learning dynamic component rendering in Vue 3 Options API and so far I've understood how :is="currentPage" works as well as v-bind="currentProps". But I can't figure out what to do with my event-listeners in the following case:

Let's say I have 3 components: A, B, C. Every component has one or more events, for now for demonstration purposes a button and when it is clicked it renders the next page:

A -> B, B -> C, C -> A etc.

// app.vue

import componentA from '~/components/componentA.vue
import componentB from '~/components/componentB.vue
import componentC from '~/components/componentC.vue

export default {
components: {
  componentA,
  componentB,
  componentC,
}
data() {
  return { 
    currentPage: 'componentA',
    currentProps: {
      label: 'go to B'
    },
  }
},
method: {
    goToA(){
      this.currentPage = 'componentA'
      this.currentProps = {label: 'go to B'}
    },
    goToB(){
      this.currentPage = 'componentB'
      this.currentProps = {label: 'go to C'}
    },
    goToC(){
      this.currentPage = 'componentC'
      this.currentProps = {label: 'go to A'}
    }
}


The static form looks like this:

// app.vue

<template>
    <componentA label="go to B" @event-of-a="goToB" />
    <componentB label="go to C" @event-of-b="goToC" />
    <componentC label="go to A" @event-of-c="goToA" />
</template>

Here the dynamic version and my problem: I can dynamically pick "currentPage" as well as "currentProps" but how to bind the right event-listener to "currentPage"?

<template>
    <component :is="currentPage" v-bind="currentProps" ?event-listener? ></component>
</template>

Upvotes: 0

Views: 613

Answers (1)

Duannx
Duannx

Reputation: 8726

You can not bind the right event listener to a dynamic component. But you can just bind all the event listeners to your dynamic component and handle it with the condition:

<component :is="currentPage" v-bind="currentProps" @event-of-a="goToB" @event-of-b="goToC" @event-of-c="goToA" 
@click="handleClickOfAllComponent(currentPage, $event)"></component>

<script setup>
function handleClickOfAllComponent(currentComponent, event) {
  if(currentComponent === 'A') {
    // handle click for component A
  }
  if(currentComponent === 'B') {
    // handle click for component B
  }
  ...
}
</script>

Upvotes: 1

Related Questions