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

Vue3中如何将第三方组件作为对象参数的Prop传递?

解决Vue3+TS中传递第三方组件到子组件的问题

错误原因

你遇到的问题核心有两点:

  1. 在模板的属性绑定中直接写<BeakerIcon/>,TS类型检查会混淆组件值与类型,抛出类型不匹配的错误;
  2. 子组件中用{{ card.icon }}的方式无法正确渲染组件(仅能渲染文本或预创建的VNode对象)。

下面提供两种可行的解决方案:


方案一:传递组件引用(推荐,灵活性更高)

这种方式是直接传递组件本身,在子组件中通过动态组件语法渲染,适合不需要给图标组件传额外属性的场景。

子组件(CardGrid.vue)修改:

<template>
  <div class="max-w-5xl mx-auto">
    <div class="ml-20 pr-72">
      <h2 class="text-4xl pb-8">{{ title }}</h2>
      <p class="font-normal text-base pb-20">{{ description }}</p>
    </div>
    <div class="grid grid-cols-2 gap-5">
      <div
        v-for="card in cards"
        :key="card.title"
        class="rounded-xl py-6 px-5 bg-cover bg-center flex flex-col justify-between items-start h-60"
        :style="{ backgroundImage: `url(${card.imageUrl})` }"
      >
        <div
          class="rounded-full p-4 bg-gradient-to-r from-prospire-blue to-prospire-light-blue"
        >
          <!-- 使用动态组件渲染传入的图标组件 -->
          <component :is="card.icon" />
        </div>
        <p class="text-white font-light text-2xl">{{ card.title }}</p>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { Component } from 'vue';

// 完善TS类型定义,明确icon为组件类型
const props = defineProps<{
  title: string;
  description: string;
  cards: Array<{
    title: string;
    imageUrl: string;
    icon: Component;
  }>;
}>();
</script>

<style scoped></style>

父组件调用修改:

直接传递BeakerIcon组件引用,而非渲染后的VNode:

<CardGrid
  :title="$t('aboutUs.cardGrid.title')"
  :description="$t('aboutUs.cardGrid.description')"
  :cards="[
    {
      title: $t('aboutUs.cardGrid.cards[0].title'),
      imageUrl: 'https://images.pexels.com/photos/5595573/pexels-photo-5595573.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1',
      icon: BeakerIcon, // 直接传组件本身
    },
  ]"
/>

方案二:传递预创建的VNode(适合需要给图标传属性的场景)

如果需要给BeakerIcon传递大小、颜色等属性,可以用Vue的h函数预创建VNode对象,再传入子组件。

父组件代码:

<script setup lang="ts">
import { h } from 'vue';
import BeakerIcon from '你的第三方组件路径';
import CardGrid from './CardGrid.vue';
</script>

<template>
  <CardGrid
    :title="$t('aboutUs.cardGrid.title')"
    :description="$t('aboutUs.cardGrid.description')"
    :cards="[
      {
        title: $t('aboutUs.cardGrid.cards[0].title'),
        imageUrl: 'https://images.pexels.com/photos/5595573/pexels-photo-5595573.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1',
        // 用h函数创建带属性的VNode
        icon: h(BeakerIcon, { size: 24, color: 'white' }),
      },
    ]"
  />
</template>

子组件类型完善:

<script setup lang="ts">
import type { VNode } from 'vue';

const props = defineProps<{
  title: string;
  description: string;
  cards: Array<{
    title: string;
    imageUrl: string;
    icon: VNode;
  }>;
}>();
</script>

子组件模板无需修改,{{ card.icon }}即可直接渲染VNode。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:25:24