Vue 3 / Nuxt 3作用域插槽,具有从属性推断的通用数据类型

6ie5vjzr  于 2022-12-04  发布在  Vue.js
关注(0)|答案(1)|浏览(227)

我想在Nuxt v3中实现一个carousel组件。该组件接收一个项目数组。该组件只实现逻辑,而不是样式或结构。
下面是我的组件:
components/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>

这里轮播的逻辑并不重要。
在父组件中,我可以这样使用组件:

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

这很好用。除此之外我还需要类型。titledescription的类型当然是任意的,因为在carousel.vue的 prop 中,项目的类型是unknown[]
我发现了这个article,它显示了如何制作一个通用组件,但我不想要这个,因为我将不得不从nuxt与自动导入系统混乱。
如何从carousel.vue prop 中的给定项进行类型推断?

oyjwcjzk

oyjwcjzk1#

您需要定义一个泛型参数。这还没有正式支持。但是,目前有an RFC说明如何支持泛型组件。
如果您使用VSCode和Volar,Volar目前有an experimental flag可供您试用。
首先,在tsconfig.json中启用vueCompilerOptions下的experimentalRfc436选项。

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

然后,您需要修改carousel.vue组件以使用<script setup>标记中的generic属性,并将其转换为使用defineProps的基于类型的方法,以便它正确地拾取泛型。

<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" generic="T extends any">
withDefaults(
  defineProps<{ items: T[]; spotlight?: number }>(), {
  spotlight: 1,
});
</script>

现在,插槽上的 prop 应该正确地从物品的类型推断出来。

相关问题