'Teleport in component from slot Vue3

I want to create tabs component for my components library. I want tabs and tab components to work like this:

<b-tabs>
  <b-tab
    :title="'tab 1'"
    :is-active="false"
  >
    tab content1
  </b-tab>
  <b-tab
    :title="'tab 2'"
    :is-active="false"
  >
    tab content2
  </b-tab>
  <b-tab
    :title="'tab 3'"
    :is-active="true"
  >
    tab content3
  </b-tab>
</b-tabs>

So we have two components and they have some props including is-active which by default will be false.

The parent component - tabs.vue will be something like this

<template>
  <section :class="mode ? 'tabs--light' : 'tabs--dark'" @change-tab="selectTab(2)">
    <div :id="`tabs-top-tabId`" class="tabs__menu"></div>
    <slot></slot>
  </section>
</template>

here we have wrapper for our single tab which will be displayed here using slot. Here in this "parent" component we are also holding selectedIndex which specify which tab is selected and function to change this value.

  setup () {
    const tabId = Math.random() // TODO: use uuid;
    const data = reactive<{selectedIndex: number}>({
      selectedIndex: 0
    })

    const selectTab = (i: number) => {
      data.selectedIndex = i
    }

    return {
      tabId,
      ...toRefs(data),
      selectTab
    }
  }

TLDR Now as you guys might already noticed in tab.vue I have div with class tabs__menu which I want to teleport some stuff into. As the title props goes into <tab> component which is displayed by the slot in tabs.vue I want to teleport from tab to tabs.

My tab.vue:

<template>
  <h1>tab.vue {{ title }}</h1>
  <div class="tab" v-bind="$attrs">
    <teleport :to="`#tabs-top-tabId`" @click="$emit('changeTab')">
      <span style="color: red">{{ title }}</span>
    </teleport>
    <keep-alive>
      <slot v-if="isActive"></slot>
    </keep-alive>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue'

export default defineComponent({
  props: {
    title: {
      type: String as PropType<string>,
      required: true
    },
    isActive: {
      type: Boolean as PropType<boolean>,
      required: true
    }
    // tabId: {
    //   type: Number as PropType<number>, // TODO: change to string after changing it to uuid;
    //   required: true
    // }
  }
})
</script>

However this span does not get teleported. When I run first snippet for this post I can't see it displayed and I don't see it in DOM.

vue3 teleport

Why teleported span doesnt display?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source