Vue3 Props 和 Emits 的类型声明
下面来看看如何给 Props 和 Emits 做类型声明。
❝ 更多关于 vue3+typescript 的内容请查看 devcursor
❞
Props
在
script setup
中,可以使用
defineProps
API,使 Props 获得完整的类型推断。
Props 声明
- 通过泛型参数定义 props 类型: 「类型声明」
<script setup lang="ts">
const props = defineProps<{
name: string
phone: number
age?: number
visible: boolean
school: string[]
</script>
-
通过
interface
或type
借助 interface 和 type,我们抽离了 props 的类型,让代码更简洁。
- interface
<script setup lang="ts">
interface Props {
foo: string
visible: boolean
bar?: number
const props = defineProps<Props>()
</script>
- type
<script setup lang="ts">
type Props = {
foo: string
visible: boolean
bar?: number
const props = defineProps<Props>()
</script>
- 从参数中推导类型: 「运行时声明」
<script setup lang="ts">
const props = defineProps({
name: { type: String, required: true }
phone: Number
age: Number
visible: Boolean
school: {
type: Array,
default () {
return []
</script>
这和 vue2 中的定义 props 类似。
Props 默认值
「基于类型的声明」 的缺陷是无法给 props 设置默认值。
我们可以借助
响应式语法糖
和
withDefaults
来实现给 props 设置默认值
- 响应式语法糖
响应式语法糖目前还在实验阶段,需要在配置中显式开启
// vite.config.js
export default {
plugins: [
vue({
reactivityTransform: true
开启后我们就可以给 props 设置默认值了。
<script setup lang="ts">
interface Props {
foo: string
visible: boolean
bar?: number
labels: string[]
// 对 defineProps() 的响应性解构
// 默认值会被编译为等价的运行时选项
const {
foo = 'hello',
visible = false,
bar = 100,
labels = ['one', 'two']
} = defineProps<Props>()
</script>
- withDefaults
withDefaults
是一个编译器宏。
<script setup lang="ts">
interface Props {
foo: string
visible: boolean
bar?: number
labels?: string[]
const props = withDefaults(defineProps<Props>(), {
foo: 'hello',
visible: false,
bar: 100
labels: () => ['one', 'two']
</script>
withDefaults 在编译时,会将以上代码编译为等价的
运行时声明 props
:
<script setup lang="ts">
const props = defineProps({
msg: { type: String, default: 'hello' }
labels: {
type: Array,
default () {
return ['one', 'two']
</script>
事件
为了让事件获得完整的类型推断,我们需要使用
defineEmits
API。
- 类型声明
<script setup lang="ts">
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'update', value: string): void
</script>
在上面的代码中,我们声明了
change
和
update
,两个事件,
id
和
value
分别为两个事件的参数。
- 运行时声明
<script setup lang="ts">
const emit = defineEmits(['change', 'update'])
</script>
如果不使用
script setup
的写法,则是:
<script>
import { defineComponent } from 'vue'
export default defineComponent({