相关文章推荐
强健的鸭蛋  ·  对话框概述 - WPF .NET | ...·  1 年前    · 
粗眉毛的镜子  ·  AWS S3 ...·  1 年前    · 
打酱油的乌冬面  ·  show processlist ...·  1 年前    · 

Vue3 Props 和 Emits 的类型声明

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

❝ 更多关于 vue3+typescript 的内容请查看 devcursor

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. 通过 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>
  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>

这和 vue2 中的定义 props 类似。

Props 默认值

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

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

  1. 响应式语法糖

响应式语法糖目前还在实验阶段,需要在配置中显式开启

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

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

<script setup lang="ts">
const props = defineProps({
  msg: { type: String, default: 'hello' }
  labels: {
    type: Array,
    default () {
      return ['one', 'two']
</script>

事件

为了让事件获得完整的类型推断,我们需要使用 defineEmits API。

  1. 类型声明
<script setup lang="ts">
const emit = defineEmits<{
  (e: 'change', id: number): void
  (e: 'update', value: string): void
</script>

在上面的代码中,我们声明了 change update ,两个事件, id value 分别为两个事件的参数。

  1. 运行时声明
<script setup lang="ts">
const emit = defineEmits(['change', 'update'])
</script>

如果不使用 script setup 的写法,则是:

<script>
import { defineComponent } from 'vue'
export default defineComponent({