Vue 3组件属性继承与扩展求助:类型交集等写法报错
解决Vue 3.3.4中扩展按钮组件Props的类型错误及组件Props继承问题
一、修复原生按钮Props扩展的类型报错
你直接使用ButtonHTMLAttributes与自定义类型交集时出现报错,是因为ButtonHTMLAttributes是Vue内部用于元素属性绑定的底层类型,并非专门为defineProps设计的合法Props类型。正确的做法是使用Vue提供的ComponentProps<'button'>来获取原生按钮的所有合法Props类型,再与自定义属性做交集:
<script setup lang="ts"> import type { ComponentProps } from 'vue' // 组合原生按钮Props与自定义属性 type ButtonProps = ComponentProps<'button'> & { variant?: 'primary' | 'secondary' color?: string } // 定义Props,此时不会报错 const props = defineProps<ButtonProps>() </script> <template> <button :class="['custom-btn', { 'custom-btn-primary': variant === 'primary', 'custom-btn-secondary': variant === 'secondary' }]" :style="{ color: color }" > <slot /> </button> </template>
另外你尝试的InstanceType<typeof HTMLButtonElement>是获取DOM按钮实例的类型,并非组件Props类型,这也是报错的原因,替换为ComponentProps<'button'>即可解决。
二、实现类似React的组件Props继承功能
Vue 3.3+同样支持从已定义的组件中推断Props类型并扩展,使用ComponentProps<typeof 组件>即可实现和React中ComponentProps类似的效果:
1. 先定义基础按钮组件(BaseButton.vue)
<script setup lang="ts"> import type { ComponentProps } from 'vue' type BaseButtonProps = ComponentProps<'button'> & { variant?: 'primary' | 'secondary' } const props = defineProps<BaseButtonProps>() </script> <template> <button :class="['base-btn', `base-btn-${variant}`]"> <slot /> </button> </template>
2. 扩展基础组件Props实现派生组件(RoundButton.vue)
<script setup lang="ts"> import type { ComponentProps } from 'vue' import BaseButton from './BaseButton.vue' // 继承BaseButton的所有Props,并添加自定义属性 type RoundButtonProps = ComponentProps<typeof BaseButton> & { borderRadius?: string } const props = defineProps<RoundButtonProps>() </script> <template> <!-- 使用v-bind="$props"传递所有继承的Props --> <BaseButton v-bind="$props" :style="{ borderRadius }"> <slot /> </BaseButton> </template>
这样派生组件RoundButton就拥有了BaseButton的所有Props,同时新增了borderRadius属性,完全符合你想要的继承扩展需求。
内容的提问来源于stack exchange,提问作者Smith
相关产品推荐
相关产品推荐

