简体   繁体   English

Vue.js 中的插槽 Inheritance 3

[英]Slot Inheritance in Vue.js 3

I'm trying to understand how/if I can define some sort of slot inheritance in Vue.js v3.我试图了解如何/是否可以在 Vue.js v3 中定义某种插槽 inheritance。 I have a Container class that defines 2 slots: title and items .我有一个Container class 定义了 2 个插槽: titleitems I extend Container in my Grid class, and I define the items slot in there.我在我的Grid class 中扩展了Container ,并在其中定义了items插槽。 When I go to use my Grid class, I would like to define the title slot.当我 go 使用我的Grid class 时,我想定义title槽。 Fiddle for reference. 提琴供参考。

Container.vue容器.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网格.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应用程序.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>

The issue is in App.vue where I have the comment in the template--I would like to pass along defining the slot in there.问题出在App.vue中,我在模板中有注释——我想传递在那里定义插槽。 Is this possible?这可能吗?

According to this , I would have to define a template that essentially passes on any slots defined on the instance. 据此,我必须定义一个模板,该模板基本上传递实例上定义的任何插槽。 So in my Grid.vue class, I would add this code:所以在我的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>

In Grid component define the title slot then inside it render its children dynamically using component :Grid组件中定义标题槽,然后在其中使用component动态呈现其子项:

 <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>

DEMO 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM