Vue 3 与 TypeScript 进阶:给 props、emits 与插槽写类型
test12026-10-174 次阅读
为什么要在组件里写类型
Vue 3 的 script setup 配合 TypeScript,能让父组件传参、子组件回调和插槽数据在编译期就被检查。相比运行时校验,类型错误在写代码时就暴露,重构也更安全。
用泛型给 props 上类型
<script setup lang="ts" generic="T">
const props = defineProps<{
list: T[];
selectedId?: string;
loading?: boolean;
}>();
const emit = defineEmits<{
(e: 'select', id: string): void;
(e: 'load-more'): void;
}>();
</script>
defineProps 直接吃泛型参数,T 由父组件传入时自动推断,列表项的类型一路透传下来。
类型安全的 emits
function onPick(id: string) {
emit('select', id);
}
// 错误用法会在编译期报错:参数数量或类型不匹配
// emit('select'); // TS 错误
把 emits 写成函数签名形式,调用时参数个数和类型都会被检查,漏传或传错类型都过不了编译。
给具名插槽的 props 写类型
<template>
<ul>
<li v-for="item in list" :key="item.id">
<slot name="row" :item="item" :index="list.indexOf(item)">
{{ item.label }}
</slot>
</li>
</ul>
</template>
<!-- 父组件使用,row 插槽的 item 自动带类型 -->
<MyList :list="data" v-slot:row="{ item }">
<span>{{ item.label }}</span>
</MyList>
工程建议
- 组件对外暴露的 props 和 emits 都写类型,内部局部变量尽量交给类型推断。
- 复杂对象用 interface 单独定义,避免在 defineProps 里内联过长结构。
- 插槽作用域数据也要标类型,否则父组件拿到的 item 会变成 any。
- 开启 vue-tsc 做独立类型检查,把它接进 CI 才不会漏掉模板里的类型错误。
T
test1
文章作者
为什么要在组件里写类型 Vue 3 的 script setup 配合 TypeScript,能让父组件传参、子组件回...
- 分类
- 技术
- 发布时间
- 2026-10-17
- 字数
- 约 1183 字
- 阅读
- 4 次
