Vue 3/Nuxt 3-Slots mit generischen Datentypen, die von Requisiten abgeleitet werden
P粉863295057
P粉863295057 2023-11-02 21:59:05
0
1
751

Ich möchte eine Karussellkomponente in Nuxt v3 implementieren. Diese Komponente empfängt eine Liste von Elementen. Diese Komponente implementiert nur Logik, keinen Stil oder Struktur.

Das ist jetzt meine Komponente:

组件/tdx/carousel.vue

<template>
  <div>
    <slot name="last"></slot>
    <div v-for="item in items">
      <slot
        name="item"
        v-bind="item"
      ></slot>
    </div>
    <slot name="next"></slot>
  </div>
</template>

<script setup lang="ts">
const props = defineProps({
  items: {
    type: [],
    required: true,
  },
  spotlight: {
    type: Number,
    default: 1,
    validator(value: number) {
      return value > 0;
    },
  },
});
</script>

Die Logik des Karussells ist hier nicht wichtig.

In der übergeordneten Komponente kann ich die Komponente so verwenden:

<template>
  <div class="container">
    <TdxCarousel :items="exampleArray">
      <template #item="{ title, description }">
        <p class="font-semibold text-2xl">{{ title }}</p>
        <hr />
        <p>{{ description }}</p>
      </template>
    </TdxCarousel>
  </div>
</template>

<script setup lang="ts">
const exampleArray = ref([
  {
    title: 'Item 1',
    description: 'Desc of item 1',
  },
  {
    title: 'Item 2',
    description: 'Desc of item 2',
  },
]);
</script>

Das funktioniert großartig. Ansonsten möchte ich tippen. titledescription 的类型当然是any,因为在 carousel.vue 的 props 中,项目的类型是 unknown[].

Ich habe diesen Artikel gefunden, der zeigt, wie man eine generische Komponente erstellt, aber ich möchte das nicht, weil ich mich mit dem automatischen Importsystem von Nuxt herumschlagen muss.

Wie implementiert man eine Typinferenz aus einem bestimmten Element im carousel.vue-Attribut?

P粉863295057
P粉863295057

Antworte allen(1)
P粉476547076

更新:2023 年 5 月

从 Vue 3.3 开始,正式支持通用组件.

您需要定义一个通用参数。修改 carousel.vue 组件以使用 标记中的 generic 属性,并将其转换为使用基于类型的defineProps 的方法,以便它正确地获取泛型。

<script setup lang="ts" generic="T extends any">
withDefaults(
  defineProps<{ items: T[]; spotlight?: number }>(), {
  spotlight: 1,
});
</script>
<template>
  <div>
    <slot name="last"></slot>
    <div v-for="item in items">
      <slot
        name="item"
        v-bind="item">
      </slot>
    </div>
    <slot name="next"></slot>
  </div>
</template>

现在,插槽上的道具将根据物品类型正确推断。

2023 年 5 月之前

在 VSCode/Volar 的早期版本中,您需要启用实验性标志 。 它需要在 vueCompilerOptions 下启用 tsconfig.json 的 experimentalRfc436 选项。

// tsconfig.json
{
  // ...
  "vueCompilerOptions": {
    "experimentalRfc436": true
  }
}

这不再是必要的,因为它在最新版本的 Volar 中默认启用。

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage