Is it possible to pass a component as props and use it in a child Component in Vue?
Summing up:
<!-- Component A -->
<template>
<div class="A">
<B>
<component :is="child_component"></component>
</B>
</div>
</template>
<script>
import B from './B.vue';
import Equipment from './Equipment.vue';
export default {
name: 'A',
components: { B, Equipment },
data() {
return { child_component: 'equipment' };
}
};
</script>
<!-- Component B -->
<template>
<div class="B">
<h1>Some content</h1>
<slot></slot> <!-- Component C will appear here -->
</div>
</template>
You can use special attribute is
for doing this kind of thing. Example of dynamic component and it's usage can be found here.
You can use the same mount point and dynamically switch between multiple components using the reserved element and dynamically bind to its is attribute:
Your code will look like following:
<template>
<div class="B">
<component :is="child_component"> Something else</component>
</div>
</template>
Here's solution to forward custom component through props of another component
:is
is special attribute and it will be used to replace your actual component and it will be ignored if you try to use it as a prop in your component. Luckily you can use something else like el
and then forward this to component
like so:
<template>
<div>
<component :is="el">
<slot />
</component>
</div>
</template>
<script>
export default {
name: 'RenderDynamicChild',
props: {
el: {
type: [String, Object],
default: 'div',
},
},
}
</script>
Any valid element you use in el
attribute will be used as a child component. It can be html or reference to your custom component or div
by default as specified in component declaration.
Passing custom component to prop is little bit tricky. One would assume you declare in a components
property of parent component and then use it for el
attribute but this doesn't work. Instead you need to have your dynamic component in data
or computed
property so you can use it in a template as a prop. Also note AnotherComponent
doesn't need to be declared in components
property.
<template>
<RenderDynamicChild :el="DynamicComponent">
Hello Vue!
</RenderDynamicChild>
</template>
<script>
import RenderDynamicChild from './DynamicChild';
import AnotherComponent from './AnotherComponent';
export default {
name: "ParentComponent",
components: { DynamicChild },
data() {
return {
DynamicComponent: AnotherComponent,
};
},
};
</script>
Using computed property for your dynamic component allows you to switch between components easily:
<script>
import DynamicChild from './DynamicChild';
import AnotherComponent from './AnotherComponent';
export default {
name: "ParentComponent",
components: { DynamicChild },
data() { return { count: 0 } },
computed: {
DynamicComponent() {
return this.count % 2 > 1 ? AnotherComponent : 'article';
},
},
};
</script>
Increase this.count
to alternate between AnotherComponent
and simple article
html element.