带有 Typescript 的 Vue3 道具类型

469 阅读1分钟

Vue 3 + TS

Vue 3 添加了非常可靠的 Typescript 支持。一个可能有点棘手的地方是键入我们定义的用于将数据传递到我们的组件中的道具。Vue 提供了一种“本机 js”的方式来执行此操作……但鉴于 js 中的动态类型系统,这显然存在局限性。下面是我发现的一些模式,可以让道具类型对 Typescript 更加友好。享受!

道具类型

import { PropType } from 'vue'

PropType是 vue 提供的一种实用程序类型,它允许您通过将 PropType 传递给您选择的类型来有效地在组件上键入道具。这是一个例子。

<template>
  <div>
    {{ label }}
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue'

export default defineComponent({
  name: 'CoolLabelComponent',
  props: {
    label: {
      type: String as PropType<string>,
      default: 'Label',
    },
  },
})
</script>

小心使用

请注意我们的 prop 定义中label我们强制 cast type: String as PropType<string>。确保您知道这里发生了什么......通过使用as PropType<string>我们强制 Typescript 将传递给我们的道具的任何值解释为一种string类型,因此您需要确信该道具实际上是一个字符串。

处理默认值

as在为 prop 提供默认值时,考虑语法尤其重要。在非打字稿 vue 代码中类似于

props: {
    label: {
      type: String,
      default: null,
    },
  },

是完全有效的。我们说我们的 label 属性是 aString但默认情况下它以null. 这是一个非常理智的模式,考虑到很多时候 prop 数据可能会被异步填充或者是可选的。

为了确保我们处理我们的null默认值,我们可以使用联合类型。null然后在我们引用 prop 时处理潜在值。看起来是这样的:

<template>
  <div>
    {{ lowerLabel }}
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue'

export default defineComponent({
  name: 'CoolLabelComponent',
  props: {
    label: {
      type: String as PropType<string | null>,
      default: null,
    },
  },
	computed: {
    lowerLabel () {
      return this.label ? this.label.toLowerCase() : 'label is null 👀'
    }
  }
})
</script>