Skip to content

Vue3 Props 声明

下面来看看如何给 Props 做类型声明。

Props

script setup 中,可以使用 defineProps API,使 Props 获得完整的类型推断。

Props 声明

  1. 通过泛型参数定义 props 类型:类型声明
<script setup lang="ts">
const props = defineProps<{
  name: string
  phone: number
  age?: number
  visible: boolean
  school: string[]
}>()
</script>
1
2
3
4
5
6
7
8
9
  1. 通过 interfacetype

借助 interface 和 type,我们抽离了 props 的类型,让代码更简洁。

  1. 从参数中推导类型:运行时声明
<script setup lang="ts">
const props = defineProps({
  name: { type: String, required: true }
  phone: Number
  age: Number
  visible: Boolean
  school: {
    type: Array,
    default () {
      return []
    }
  }
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

这和 vue2 中的定义 props 类似。

  1. defineComponents

在没有使用 script setup 的情况下,需要使用 defineComponents 来实现 props 的类型推导。

import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    message: String,
    name: { type: String, required: true }
    phone: Number
    age: Number
    visible: Boolean
    school: {
      type: Array,
      default () {
        return []
      }
    }
  },
  setup(props) {
    props.message // string 类型
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

外部类型定义 props

vue@3.3 之前的版本,vue3 还未支持从外部导入类型来定义 props,这是一个非常大的缺陷

这个缺陷在 vue@3.3+ 版本中得到解决:编译器现在可以解析导入的类型,并支持有限的复杂类型

也就是说:

vite-plugin-vue-type-imports

对于使用小于 3.3 版本的 vue3,可以使用该方法来处理。

通过 vite-plugin-vue-type-imports 能实现使用外部类型,直到官方支持该特性。

Props 默认值

基于类型的声明的缺陷是无法给 props 设置默认值。

我们可以借助响应式语法糖withDefaults 来实现给 props 设置默认值

  1. 响应式语法糖

警告

响应式语法糖是一个实验性功能,将会在vue@3.4移除,如要使用,请通过 Vue Macros 插件。

响应式语法糖需要在配置中显式开启

// vite.config.js
export default {
  plugins: [
    vue({
      reactivityTransform: true
    })
  ]
}
1
2
3
4
5
6
7
8

开启后我们就可以给 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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  1. 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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

withDefaults 在编译时,会将以上代码编译为等价的运行时声明 props

<script setup lang="ts">
const props = defineProps({
  foo: { type: String, default: 'hello' },
  visible: { type: Boolean, default: false },
  bar: { type: Number, default: 100 },
  labels: {
    type: Array,
    default () {
      return ['one', 'two']
    }
  }
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13

推荐使用 withDefaults 来设置 props 默认值。

Vue3 Props 声明 has loaded