Vue3中如何将第三方组件作为对象参数的Prop传递?
解决Vue3+TS中传递第三方组件到子组件的问题
错误原因
你遇到的问题核心有两点:
- 在模板的属性绑定中直接写
<BeakerIcon/>,TS类型检查会混淆组件值与类型,抛出类型不匹配的错误; - 子组件中用
{{ 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
相关产品推荐
相关产品推荐

