Search code examples
javascriptvue.jsvuejs2vue-component

Is it possible to pass a component as props and use it in a child Component in Vue?


In a Vue 2.0 app, let's say we have components A, B and C.

A declares, registers and uses B

Is it possible to pass C from A to B?

Something like this:

<template>
  <div class="A">
    <B :child_component="C" />
  </div>
</template>

And use C in B somehow.

<template>
  <div class="B">
    <C>Something else</C>
  </div>
</template>

The motivation: I want to create a generic component B that is used in A but receives from A its child C. Actually A will use B several times passing different 'C's to it.

If this approach is not correct, what is the proper way of doing it in Vue?

Answering @Saurabh

Instead of passing as props, I tried the suggestion inside B.

<!-- this is where I Call the dynamic component in B -->

<component :is="child_component"></component>

//this is what I did in B js
components: {
 equip: Equipment
}, 
data () {
 return {
   child_component: 'equip',
   _list: []
 }
}

Basically I'm trying to render Equipment, but the dynamic way

I get 3 errors in console and a blank page

[Vue warn]: Error when rendering component at /home/victor/projetos/tokaai/public/src/components/EquipmentFormItem.vue:

Uncaught TypeError: Cannot read property 'name' of undefined

TypeError: Cannot read property 'setAttribute' of undefined

Apparently I'm doing something wrong


Solution

  • You can use special attribute is for doing this kind of thing. Example of dynamic component and its 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.

    Here's how is can be used with either an imported component or one passed as a prop:

    <template>
      <div class="B">
        <component :is="myImportedComponent">Something</component>
        --- or ---
        <component :is="myPassedComponent">Something else</component>
      </div>
    </template>
    
    <script>
    import myImportedComponent from "@/components/SomeComponent.vue"
    
    export default {
        props: {
            myPassedComponent: Object
        },
    
        components: {
            myImportedComponent
        },
    }
    </script>