I am conditionally rendering a child component using render function. Here is an example of the parent component with the child component:
<Parent :index="1">
<Child> ... </Child>
<Child> ... </Child>
<Child> ... </Child>
</Parent>
in the render function of Parent
component, I have the following code to conditionally render the child component like this:
return () => {
const content = slots.default?.();
const children = content?.filter(child => child.type === Child);
const childToRender = children?.[props.index] ?? h('div')
return h('div', {}, () => [childToRender]);
}
the code is working as expected.
However, I would like to wrap one of the child component with another component. For example like this:
<Parent :index="1">
<Child> ... </Child>
<ChildWrapper> ... </ChildWrapper>
<Child > ... </Child>
</Parent>
where ChildWrapper.vue
looks like this:
<template>
<Child> <slot/> </Child>
</template>
which evidently the filter function (content?.filter(child => child.type === Child)
) will not pick up the Child
component in the ChildWrapper
component.
If I inspect the ChildWrapper VNode’s children property, it shows an object (with the default slot function) instead of an array with Child
component which I expected. So my question is how do I get hold of the nested Child
component?
Background of problem
Say the parent component is a Tab
or a Carousel
component and the child component is a TabItem
or CarouselItem
component. The reason I made a ChildWrapper
component is to extend/override some of the props in the default Child
component. The parent and child components are from a component library, and it has no knowledge of what ChildWrapper
is, so the parent component can’t control how ChildWrapper
should render.
2
Answers
2 approaches.
In the Parent component, use whatever logic is required set the state value.
Then, move the conditional render condition out of the Parent and into the child itself, while importing the state: like,
This way, the child can wrap itself when necessary and your parents component doesn’t need to be refactored.
I believe that obtaining specific, deeply nested child components directly from the parent is not a recommended approach. Child components may be nested deeply, beyond just one level.
Using
provide
andinject
allows you to achieve your goal seamlessly, in my opinion.I will provide a simple example to illustrate this.
Parent component:
Child component:
The provided code is not complete, but I believe the main idea is conveyed.