I am having difficulty to make use of named slot from children in parent component. So I am making tabs component with main Tabs and child Tab components. My Tabs:
<template>
<div class="tabsMainContainer">
<div class="tabsContainer">
<ul class="tabsHeader">
<li
v-for="(tab, index) in tabs"
:key="tab.title"
:class="{tabActive: (index == selectedIndex)}"
@click="selectTab(index)"
>
<slot name="icon"/>
{{ tab.title }}
</li>
</ul>
</div>
<div class="tabsContent"><slot/></div>
</div>
</template>
I get tabs object with this.$children
and then my Tab component:
<template>
<div v-show="isActive" class="tab">
<slot name="icon"/>
<slot/>
</div>
</template>
And use of that:
<Tabs class="tabsComponent">
<Tab title="first">
<template v-slot:icon>Icon</template>
Content
</Tab>
<Tab title="second">Content second</Tab>
</Tabs >
while Content as such works fine, it appears in default slot, the icon slot also appears in default slot in main Tab component. How can I get icon slot from children, and display it in icon slot of main Tab component?
I also had a same kind of requirement. What I did was adding slot
inside the main component's slot
with the same name
In your Tab component
<template>
<div v-show="isActive" class="tab">
<template v-slot:icon>
<slot name="icon" />
</template>
</div>
</template>
First of all, I use google translate. Sorry, I may have spelled it wrong.
https://stackoverflow.com/a/64568036
I got an example from@ingrid-oberbüchler .
Layout.vue
<Tabs class="tabsComponent">
<Tab title="first">
<template v-slot:icon>Icon</template>
Content
</Tab>
<Tab title="second">Content second</Tab>
</Tabs>
Tabs.vue
<template>
<div class="title">
{{ tabsProvider.tabs[tabsProvider.selectedIndex].props.title }}
</div>
<div class="content">
<slot/>
</div>
<div class="icon">
<component :is="tabsProvider.tabs[tabsProvider.selectedIndex].children.icon"/>
</div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
data() {
return {
tabsProvider: {
selectedIndex: 0,
tabs: [],
count: 0,
},
};
},
provide() {
return {
$tabsProvider: this.tabsProvider,
};
},
created() {
this.tabsProvider.tabs = this.$slots.default().filter((child) => child.type.name === "Tab");
},
}
</script>
Tab.vue
<template>
<div v-show="isActive">
<slot />
</div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
name: "Tab",
props: {
title: {
type: String,
},
},
inject: ["$tabsProvider"],
data() {
return {
index: 0,
isActive: false,
};
},
beforeMount() {
this.index = this.$tabsProvider.count;
this.$tabsProvider.count++;
this.isActive = this.index === this.$tabsProvider.selectedIndex;
},
watch: {
"$tabsProvider.selectedIndex": {
handler(val, oldVal) {
this.isActive = this.index === this.$tabsProvider.selectedIndex;
},
deep: true,
},
},
});
</script>
Simplest example
let's admit x component is parent
<div class="x">x component</div>
let's admit y component is child
<div class="y">y component</div>
How to be process?
<Ycomponent>
<slot name="example1"/>
<slot name="example2"/>
<slot name="example3"/>
</Ycomponent>
<Xcomponent>
<Ycomponent>
<button slot="example1">button</button>
<span slot="example2">Span</span>
<img slot="example3" src="/"/>
</Ycomponent>
</Xcomponent>
I hope I could help.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.