Vue3组件如何定义带预定义键的对象数组类型Props
Vue3 约束数组类型Props的内部元素结构
使用Composition API定义数组类型Props的基础写法仅校验传入值为数组,不会检查数组内部元素结构,示例代码如下:
<script setup> defineProps({ items: { type: Array, required: true, }, }); </script>
这种写法下传入普通对象数组不会有问题,比如下面这种结构:
[ { username: "foo", email: "foo@example.com" }, { username: "bar", email: "bar@example.com" } ]
但如果要强制约束数组内每个对象必须包含username和email属性,让调用组件的开发者明确知晓必填结构,可以根据项目技术栈选以下两种实现方式:
- 运行时自定义校验:纯JS项目可用,开发环境控制台会抛出明确的校验警告
- TS类型约束:TS项目推荐,IDE会实时提示类型错误,开发体验更好
运行时自定义校验实现
Vue的Props配置原生支持自定义validator函数,直接在函数里遍历数组检查每一项的字段即可,校验逻辑可以按需自定义:
<script setup> defineProps({ items: { type: Array, required: true, validator(items) { // 检查每一项都同时存在username和email字段 const isValid = items.every(item => { return Object.hasOwn(item, 'username') && Object.hasOwn(item, 'email') }) if (!isValid) { console.warn('items数组的每一项都必须包含username和email属性') } return isValid } } }) </script>
如果需要做更严格的校验,比如要求两个字段都是字符串类型,直接在判断条件里补充typeof item.username === 'string'这类逻辑即可。
TypeScript 类型约束实现
如果项目使用TypeScript,直接给defineProps传入泛型类型定义即可,不需要额外写冗余的运行时代码,IDE会自动推导Props类型,传入不符合结构的值时会实时标红提示:
<script setup lang="ts"> // 定义数组元素的结构类型 interface UserInfo { username: string email: string } defineProps<{ items: UserInfo[] }>() </script>
如果需要同时兼顾运行时兜底校验,可以把两种写法结合使用:TS做编译阶段的类型拦截,validator做运行时的异常提示,双重保障避免非法传值。
内容的提问来源于stack exchange,提问作者Robert Strauch
相关产品推荐
相关产品推荐

