翻译 - 如何在 Vue 中使用Props变体

构建在保持类型安全的同时处理多重变化的 Vue 组件可能很棘手。让我们深入研究如何使用变体 Props 模式(VPP) - 一种强大的方法,它使用 TypeScript 的可区分联合类型与 Vue 的组合式 API 来创建真正类型安全的组件变体。

长话短说

Vue 中的 Variant Props 模式将 TypeScript 的可区分联合与 Vue 的 prop 系统相结合,以创建类型安全的组件变体。我们不使用复杂类型实用程序,而是将不兼容的 props 显式标记为 never,以防止在编译时混合 props:

该模式提供了编译时安全性、出色的 IDE 支持和可靠的 vue-tsc 兼容性。非常适合需要多个互斥道具组合的组件。

问题:混合 Props 噩梦

想象一下:您正在构建一个需要处理成功和错误状态的通知组件。每个类型都有自己特定的属性:

  • 成功需要 messageduration
  • 错误需要 errorCoderetryable 标志

如果没有适当的安全类型,开发人员可能会意外的混用这些 props

html
<!-- 🚨 Mixing success and error props -->
<NotificationAlert
  variant="primary"
  title="Data Saved"
  message="Success!"
  errorCode="UPLOAD_001"
  :duration="5000"
  @close="handleClose"
/>

简单的解决方案不起作用

您的第一直觉可能是定义单独的接口:

有什么问题?这种方法允许开发人员同时使用 success 和 error props - 绝对不是我们想要的!

使用 never

TypeScript 提示: never 类型是 TypeScript 中的一种特殊类型,表示从未出现的值。当属性被标记为 never 时,TypeScript 确保永远不能将值分配给该属性。这使得它非常适合创建互斥的 props,因为它可以防止开发人员意外地使用不应该同时存在的 props。 never 类型通常出现在 TypeScript 中的几种场景中:

  • 永不返回的函数(抛出错误或具有无限循环)
  • switch 语句中的详尽类型检查
  • 不可能的类型交叉(例如 string & number)
  • 使属性互斥,就像我们在这种模式中所做的那样

使其与当前的 defineProps 实现兼容的主要技巧是使用 never 来显式标记未使用的变体道具。

把它们放在一起

这是使用 Variant Props 模式的完整通知组件:

vue playground preview

结论

Variant Props Pattern (VPP) 提供了一种构建类型安全的 Vue 组件的强大方法。虽然 Vue 团队正在努力改进 vuejs/core#8952 中对受歧视联合体的本机支持,但这种模式今天提供了一个实用的解决方案:

不幸的是,目前不起作用的是使用像 Xor 这样的辅助实用程序类型,这样我们就不必手动将未使用的变体属性标记为从不。当你这样做时,你会从 vue-tsc 收到错误。

Xor 等辅助类型的示例:

翻译:Vue3 组合式API 完全指南

心经

评论区

评论加载中...