Vue.js中如何在一个组件中嵌套使用另一个组件?
实现将
<bread>组件作为<my-comp>的craps属性传入的流程 1. 改造<my-comp>的Props定义
首先修改<my-comp>的props配置,让craps同时支持字符串和组件VNode(Vue虚拟节点)类型:
Vue 2 实现
<script> export default { props: { title: { type: String, required: true }, craps: { type: [String, Object], // 允许字符串或VNode对象 default: '' } } } </script>
Vue 3 (Script Setup) 实现
<script setup> import { defineProps } from 'vue' const props = defineProps({ title: { type: String, required: true }, craps: { type: [String, Object], default: '' } }) </script>
2. 在<my-comp>中渲染传入的内容
根据craps的类型,在<my-comp>中分别处理字符串和组件的渲染:
Vue 2 模板处理
<template> <div class="my-comp"> <h2>{{ title }}</h2> <!-- 渲染字符串类型的craps --> <div v-if="typeof craps === 'string'" class="craps-text">{{ craps }}</div> <!-- 渲染组件VNode --> <component v-else :is="craps"></component> </div> </template>
Vue 3 渲染函数处理(更灵活)
用渲染函数直接处理不同类型的craps:
<script setup> import { defineProps, h } from 'vue' const props = defineProps({ title: String, craps: [String, Object] }) function renderMyComp() { const content = typeof props.craps === 'string' ? h('div', props.craps) : props.craps return h('div', [ h('h2', props.title), content ]) } </script> <template> <renderMyComp /> </template>
3. 父组件中传递<bread>给craps
根据你使用的模板语法,选择对应的传递方式:
方式一:JSX/TSX 环境(符合你期望的写法)
如果项目支持JSX/TSX,可以直接按你想要的方式传入:
<script setup lang="tsx"> import MyComp from './MyComp.vue' import Bread from './Bread.vue' const record = [ { title: 'name', item: 'one' }, { title: 'name', item: 'two' } ] </script> <template> <MyComp title="title" craps={<Bread :record="record" />} /> </template>
方式二:普通Vue模板环境
用h函数创建<bread>的VNode后传递:
<script setup> import { h } from 'vue' import MyComp from './MyComp.vue' import Bread from './Bread.vue' const record = [ { title: 'name', item: 'one' }, { title: 'name', item: 'two' } ] // 创建Bread组件的虚拟节点 const breadVNode = h(Bread, { record }) </script> <template> <MyComp title="title" :craps="breadVNode" /> </template>
可选优化:用插槽替代属性传递
Vue中更常规的组件嵌套方式是使用插槽,如果你不需要严格用craps属性传递,可以改成:
<!-- 父组件 --> <MyComp title="title"> <Bread :record="record" /> </MyComp> <!-- MyComp组件 --> <template> <div> <h2>{{ title }}</h2> <slot></slot> <!-- 渲染插槽中的Bread组件 --> </div> </template>
内容的提问来源于stack exchange,提问作者simon
相关产品推荐
相关产品推荐

