Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a vue component to a child component

Tags:

vue.js

I'm trying to create a Vue component that will accept a component as parameter to display data, but I have trouble figuring out how to make it work. If I register the display component globally (using Vue.component()), it works, but if I register it locally, I get the following error:

[Vue warn]: Unknown custom element: <my-link> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

Can anybody tell me how to make this work with local registration?

Main Component:

<template>
    <div>
        <my-list :items="items" :renderer="renderer"></my-list>
    </div>
</template>
<script>
import MyList from './my-list'
export default {
    components: {
        'my-list': MyList,
        'my-link': {
            props: { data: Object },
            template: '<span>{{ data.Name }}</span>'
        }
    },
    data() {
        return {
            items: [
                { id: 1, Name: 'One' },
                { id: 2, Name: 'Two' }
            ],
            renderer: 'my-link'
        }
    }
}
</script>

MyList Component:

<template>
    <div>
        <div v-for="item in items" :key="item.id">
            <div :is="renderer" :data="item"></div>
        </div>
    </div>
</template>
<script>
export default {
    props: { 
        items: Array,
        renderer: String
    }
}
</script>
like image 716
laurian Avatar asked Oct 30 '22 05:10

laurian


1 Answers

You're seeing this warning because you have not registered my-link in the scope of the component you are trying to use it in. You registered my-link in the Main component, but the MyList component doesn't have access to that scope.

Moving the component definition of my-link to the components property of the MyList component will fix the issue.


Alternatively, you could create a new single-file component for the my-link component, and import it wherever you want to use it. Just like you do for the my-list component.


If you want the my-link component to be globally accessible, you'll need to register it via Vue.component wherever you are instantiating the root Vue instance (probably in src/main.js if you used vue-cli to set up your project):

Vue.component('my-link', {
  props: { data: Object },
  template: '<span>{{ data.Name }}</span>'
});

new Vue({
  el: '#app',
  ...
});

If you really want to pass a component in to a child component, without registering to that child component, you can pass the component definition as a property, as suggested by @BertEvans.

like image 178
thanksd Avatar answered Dec 20 '22 21:12

thanksd