Телепорт в компоненте из слота Vue3
Я хочу создать компонент вкладок для моей библиотеки компонентов. я хочу
tabs
и компоненты для работы следующим образом:
<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>
Итак, у нас есть два компонента, и у них есть некоторые реквизиты, включая is-active, который по умолчанию будет ложным.
Родительский компонент -
tabs.vue
будет что-то вроде этого
<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>
здесь у нас есть обертка для нашего сингла
tab
который будет отображаться здесь с помощью слота. Здесь, в этом «родительском» компоненте, мы также держим
selectedIndex
которые определяют, какая вкладка выбрана, и функция для изменения этого значения.
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
}
}
TL; DR Теперь, как вы, ребята, уже могли заметить, у меня есть div с классом
tabs__menu
в который я хочу телепортировать что-то. Как
title
реквизит входит в
<tab>
компонент, который отображается слотом в tabs.vue, я хочу телепортироваться с вкладки на вкладки.
Мой
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>
Однако это
span
не телепортируется. Когда я запускаю первый фрагмент этого сообщения, я не вижу его отображаемого и не вижу в DOM.
Почему телепортированный интервал не отображается?
1 ответ
Недавно я столкнулся с этой проблемой при использовании element-plus с утилитами vue test и Jest. Не уверен, что это поможет, но вот мой обходной путь.
const wrapper = mount(YourComponent, {
global: {
stubs: {
teleport: { template: '<div />' },
},
},
})