Vue.js 3 中的插槽继承
Slot Inheritance in Vue.js 3
我正在尝试理解 how/if 我可以在 Vue.js v3 中定义某种插槽继承。我有一个 Container
class 定义了 2 个槽:title
和 items
。我在 Grid
class 中扩展了 Container
,并在其中定义了 items
插槽。当我去使用我的 Grid
class 时,我想定义 title
插槽。 Fiddle供参考。
Container.vue
<template>
<div>
<header v-if="showTitle">
<slot name="title" />
</header>
<main v-if="showItems">
<slot name="items" />
</main>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "MyContainer",
computed: {
showTitle() {
return !!this.$slots.title;
},
showItems() {
return !!this.$slots.items;
},
},
});
</script>
Grid.vue
<template>
<MyContainer>
<template #items>
<span>Here are my items</span>
</template>
</MyContainer>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import MyContainer from "@/components/base/Container";
export default defineComponent({
name: "MyGrid",
extends: MyContainer,
components: { MyContainer },
});
</script>
App.vue
<template>
<div id="app">
<MyGrid>
<!-- How can I pass this along to MyGrid's base class? -->
<template #title>
<span>This is my title!</span>
</template>
</MyGrid>
</div>
</template>
<script>
import MyGrid from "@/components/base/Grid";
export default {
name: "App",
components: {
MyGrid,
},
};
</script>
问题出在 App.vue
中,我在模板中有评论——我想传递其中定义的插槽。这可能吗?
根据 this,我必须定义一个模板,该模板基本上传递实例上定义的任何插槽。所以在我的 Grid.vue
class 中,我会添加以下代码:
<template>
<MyContainer>
<template #items>
<span>Here are my items</span>
</template>
<!-- Added this template -->
<template v-for="(_, name) in $slots" v-slot:[name]="slotData">
<slot :name="name" v-bind="slotData" />
</template>
</MyContainer>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import MyContainer from "@/components/base/Container";
export default defineComponent({
name: "MyGrid",
extends: MyContainer,
components: { MyContainer },
});
</script>
在 Grid
组件中定义标题槽,然后在其中使用 component
动态呈现其 children :
<MyContainer>
<template #title>
<component v-for="(el, i) in $slots.title()" :is="el" :key="i">
</component>
</template>
<template #items>
<span>Here are my items</span>
</template>
</MyContainer>
</template>
我正在尝试理解 how/if 我可以在 Vue.js v3 中定义某种插槽继承。我有一个 Container
class 定义了 2 个槽:title
和 items
。我在 Grid
class 中扩展了 Container
,并在其中定义了 items
插槽。当我去使用我的 Grid
class 时,我想定义 title
插槽。 Fiddle供参考。
Container.vue
<template>
<div>
<header v-if="showTitle">
<slot name="title" />
</header>
<main v-if="showItems">
<slot name="items" />
</main>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "MyContainer",
computed: {
showTitle() {
return !!this.$slots.title;
},
showItems() {
return !!this.$slots.items;
},
},
});
</script>
Grid.vue
<template>
<MyContainer>
<template #items>
<span>Here are my items</span>
</template>
</MyContainer>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import MyContainer from "@/components/base/Container";
export default defineComponent({
name: "MyGrid",
extends: MyContainer,
components: { MyContainer },
});
</script>
App.vue
<template>
<div id="app">
<MyGrid>
<!-- How can I pass this along to MyGrid's base class? -->
<template #title>
<span>This is my title!</span>
</template>
</MyGrid>
</div>
</template>
<script>
import MyGrid from "@/components/base/Grid";
export default {
name: "App",
components: {
MyGrid,
},
};
</script>
问题出在 App.vue
中,我在模板中有评论——我想传递其中定义的插槽。这可能吗?
根据 this,我必须定义一个模板,该模板基本上传递实例上定义的任何插槽。所以在我的 Grid.vue
class 中,我会添加以下代码:
<template>
<MyContainer>
<template #items>
<span>Here are my items</span>
</template>
<!-- Added this template -->
<template v-for="(_, name) in $slots" v-slot:[name]="slotData">
<slot :name="name" v-bind="slotData" />
</template>
</MyContainer>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import MyContainer from "@/components/base/Container";
export default defineComponent({
name: "MyGrid",
extends: MyContainer,
components: { MyContainer },
});
</script>
在 Grid
组件中定义标题槽,然后在其中使用 component
动态呈现其 children :
<MyContainer>
<template #title>
<component v-for="(el, i) in $slots.title()" :is="el" :key="i">
</component>
</template>
<template #items>
<span>Here are my items</span>
</template>
</MyContainer>
</template>