You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue能否像React一样透传插槽、事件与属性?以PrimeVue Button为例

在Vue中实现类似React的Props透传(含插槽、事件自动传递)

Vue完全可以实现类似React的{...props}式透传,同时能自动处理插槽、事件传递,无需手动逐个声明。以下是针对PrimeVue Button组件的优化方案:

一、Props传递与Class合并优化

无需手动声明空接口,直接利用Vue的解构和v-bind传递剩余props,同时保留TypeScript类型校验:

<template>
  <Button
    v-bind="props"
    :class="twMerge('flex', classProp ?? '')"
  >
    <!-- 插槽透传部分见下文 -->
  </Button>
</template>

<script setup lang="ts">
import { Button, ButtonProps } from 'primevue'
import twMerge from 'tailwind-merge'

// 解构出需要自定义的class,剩余props自动保留原组件类型
const { class: classProp, ...props } = defineProps<ButtonProps>()
</script>

这里v-bind="props"等价于React的{...props},会自动传递除class外的所有props给PrimeVue Button。

二、自动传递所有插槽(无需逐个定义)

Vue 3支持两种方式自动透传所有插槽,覆盖默认插槽和命名插槽:

方式1:最简自动透传

直接写入<slot />,Vue会自动把父组件传入的所有插槽内容透传给内部Button:

<template>
  <Button
    v-bind="props"
    :class="twMerge('flex', classProp ?? '')"
  >
    <slot />
  </Button>
</template>

方式2:显式遍历插槽(更可控)

如果需要对插槽做额外处理,可遍历$slots动态传递所有插槽,确保无遗漏:

<template>
  <Button
    v-bind="props"
    :class="twMerge('flex', classProp ?? '')"
  >
    <template v-for="(_, slotName) in $slots" #[slotName]="slotProps">
      <slot :name="slotName" v-bind="slotProps" />
    </template>
  </Button>
</template>

这种方式适合组件有多个命名插槽的场景(比如PrimeVue Button的icon、label插槽)。

三、自动传递所有事件

通过v-on="$attrs"可自动传递所有监听的事件,$attrs包含了所有未被声明为props的属性(包括事件):

<template>
  <Button
    v-bind="props"
    v-on="$attrs"
    :class="twMerge('flex', classProp ?? '')"
  >
    <slot />
  </Button>
</template>

不管父组件绑定了@click、@mouseenter还是PrimeVue Button特有的@click:icon等事件,都会自动透传给内部组件,无需手动声明defineEmits。

完整最终代码

整合所有优化点后的自定义Button组件:

<template>
  <Button
    v-bind="props"
    v-on="$attrs"
    :class="twMerge('flex', classProp ?? '')"
  >
    <template v-for="(_, slotName) in $slots" #[slotName]="slotProps">
      <slot :name="slotName" v-bind="slotProps" />
    </template>
  </Button>
</template>

<script setup lang="ts">
import { Button, ButtonProps } from 'primevue'
import twMerge from 'tailwind-merge'

const { class: classProp, ...props } = defineProps<ButtonProps>()
</script>

关键说明

  • Props透传:v-bind="props"实现类似React的剩余props传递,保留原组件类型校验
  • 事件透传:v-on="$attrs"自动传递所有事件,无需手动声明事件类型
  • 插槽透传:遍历$slots确保所有命名插槽都被正确传递
  • Class合并:twMerge避免默认类与传入类冲突,符合Tailwind CSS最佳实践

内容的提问来源于stack exchange,提问作者Amereth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:31:03