vue3 <script setup lang="ts" generic="T"> 这样的组件如何传入泛型?

<script setup lang="ts">
    import A from "./A.vue";
<script>

<template>
  <A></A>
</template>

// A.vue
<script setup lang="ts" generic="T">
    ...
<script>
<template>
  ...
</template>

使用的时候在哪里定义T呢?
还是这组件不是这样用的?
文档地址

阅读 3.3k
2 个回答

不用定义,vue-tsc 会自动推断。

<!-- list.vue -->
<script setup lang="ts" generic="T">
defineProps<{
    data: T[];
}>();

const $emit = defineEmits<{
    (e: 'click-item', item: T): void;
}>();

const handleClickItem = (item: T) {
    $emit('click-item', item);
}
</script>

<template>
    <ul>
        <li v-for="(item, index) in data" :key="index" @click="handleClickItem(item)">
            {{ item }}
        </li>
    </ul>
</template>
<!-- demo.vue -->
<script setup lang="ts">
import { ref } from 'vue';
import List from './list.vue';

const data = ref([
    { id: 1, name: 'a' },
    { id: 2, name: 'b' },
    { id: 3, name: 'c' }
]);
</script>

<template>
    <List :data="data" @click-item="(item) => console.log(item)" />
</template>

此时你鼠标放上去,就能看到类型自动推断了:

image.png


如果非要显式指定泛型也行,但 template 是没办法了,得用 tsx:

<script lang="tsx">
import { defineComponent, ref } from 'vue';
import List from './list.vue';

export default defineComponent({
    setup() {
        type MyItem = { id: number; name: string };
        const data = ref<MyItem[]>([
            { id: 1, name: 'a' },
            { id: 2, name: 'b' },
            { id: 3, name: 'c' }
        ]);

        return () => <List<MyItem> data={data.value} />;
    }
});
</script>

A.vue:

<script setup lang="ts" generic="T">
import { defineProps } from 'vue';

const props = defineProps<{
  items: T[];
  selected: T | null;
}>();
</script>

<template>
  <div>
    <div v-for="item in props.items" :key="item">
      {{ item }}
    </div>
    <div>
      Selected: {{ props.selected }}
    </div>
  </div>
</template>

ParentComponent.vue


<script setup lang="ts">
import { ref } from 'vue';
import A from './A.vue';

const items = ref<string[]>(['item1', 'item2', 'item3']);
const selected = ref<string | null>(null);
</script>

<template>
  <A :items="items" :selected="selected"></A>
</template>
推荐问题
logo
Microsoft
子站问答
访问
宣传栏