Vue 3 显著扩展了它的功能,最近我一直在使用Composition API和Typescript来开发我的项目,很高兴看到开发人员体验如何通过适当的类型安全性和支持得到提升,同时解决了 Vue 2 臭名昭著的缺点。
此外,VSCode 的 Typescript Volar 扩展的弃用也使一切变得更快、更少黑客攻击(不再需要禁用内置 typescript 来接管模式)。{#c66b}
虽然使用 Vue 3 和 TypeScript 是一件非常有趣的事情,但必须承认在项目中利用类型时会遇到某些限制。下面让我们深入探讨这些限制和注意事项。{#beba}
值得注意的是,本文中关于使用 声明组件 props 的所有内容defineProps
也适用于使用 定义组件事件发出defineEmits
。{#d17c}
使用 TypeScript 在 Vue 3 的 Composition API 中声明组件 props 的新方法涉及使用一个名为 的编译器宏defineProps
,该宏仅在<script setup>
标记内。此宏无需导入,可以以常规方式声明 props:{#d312}
// MyComponent.vue
<script setup lang= "ts" >
const props = defineProps ({
foo : Boolean
})
</script>
Vue 现在支持仅类型的 prop 声明,方法是为defineProps
type 提供文字类型参数,并在不传递任何值的情况下调用该函数。这会将类型推断委托给编译器,无缝生成运行时类型声明:
// MyComponent.vue
<script setup lang= "ts" >
const props = defineProps<{
foo : string
bar?: number
}>()
</script>
但问题出在哪里呢? {#41d2}
然而,尽管这种体验看似神奇,但也存在局限性。虽然编译器可以熟练地推断简单情况的类型,但它在处理复杂类型或逻辑密集型类型声明时会遇到挑战,导致 Vue 抛出错误。例如:{#bb30}
// MyComponent.vue - Error
<script setup lang= "ts" >
type SimpleProps = {
foo : string ,
bar?: boolean ,
bazz?: number
}
type InferredProps = {
[S in keyof SimpleProps ]: boolean
}
const props = defineProps< InferredProps >()
</script>
此代码导致 vue 编译器错误:Error: [@vue/compiler-sfc] Failed to resolve index type into finite keys
为了解决这个问题,Vue 可以单独推断每个 prop,而不是整个 props 对象:
// MyComponent.vue - Works
<script setup lang= "ts" >
type SimpleProps = {
foo : string ,
bar?: boolean ,
bazz?: number
}
type InferredProps = {
[S in keyof SimpleProps ]: boolean
}
type AcceptableInferredProps = {
foo : InferredProps [ 'foo' ],
bar?: InferredProps [ 'bar' ],
bazz?: InferredProps [ 'bazz' ]
}
const props = defineProps< AcceptableInferredProps >()
</script>
类似地,由于同样的潜在问题,使用接口语法时也会出现错误:
// MyComponent.vue - Error
<script setup lang= "ts" >
interface SimpleProps {
foo : string ,
bar?: boolean ,
bazz?: number
}
type InferredProps = {
[S in keyof SimpleProps ]: boolean
}
interface Props extends InferredProps {
qux : string
}
const props = defineProps< Props >()
</script>
这会导致以下错误:Error: [@vue/compiler-sfc] Failed to resolve extends base type.
并且可以通过使用我们之前的方法来解决这个问题,即独立声明每个 prop 而不是整个 props 对象。{#438b}
总而言之,Vue 3 对 Typescript 具有很好的支持,我强烈建议使用它来提升项目的 DX,但正如我们所见,我们应该小心并注意其局限性。{#c5f0}