mahesh shah
mahesh shah

Reputation: 68

how to create nesting Components in Vue.js

I have created one demo for creating nesting component in vue.js.

but it is not working.

See below code...

Vue.component('component-a', {
  template: '<div><span>Hi</span><slot></slot></div>',
  components: {
    'component-b': {
      template: '<div>Hello</div>'
    }
  }
});

new Vue({
  el: '#app'
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
<component-a>
  <component-b></component-b>
  </component-a>
  </div>

But component-b is not rendering.

Can anyone tell me what I am doing wrong?

Upvotes: 0

Views: 970

Answers (2)

acdcjunior
acdcjunior

Reputation: 135762

You declare component-b in component-a. Local registering of components make them only accessible withing the components they are registered (declared), not globally, not even to their children.

And, in your code, component-b is being used by the root component, not by component-a. component-a's template is:

<div><span>Hi</span><slot></slot></div>

There's no use of component-b there. With:

new Vue({
  el: '#app'
});
<div id="app">
  <component-a>
    <component-b></component-b>
  </component-a>
</div>

You do are using component-b in the root's template. But it was not registered nowhere the root component can see.

You have some alternatives.


Move the registration to the root, where it is used:

Vue.component('component-a', {
  template: '<div><span>Hi</span><slot></slot></div>'
});

new Vue({
  el: '#app',
  components: {
    'component-b': {
      template: '<div>Hello</div>'
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
  <component-a>
    <component-b></component-b>
  </component-a>
</div>

Register it globally, like component-a

Vue.component('component-a', {
  template: '<div><span>Hi</span><slot></slot></div>',
});
Vue.component('component-b', {
  template: '<div>Hello</div>'
});

new Vue({
  el: '#app'
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
  <component-a>
    <component-b></component-b>
  </component-a>
</div>

Or use it inside component-a instead of the root and move the slot (changes semantics)

Vue.component('component-a', {
  template: '<div><span>Hi</span><component-b><slot></slot></component-b></div>',
  components: {
    'component-b': {
      template: '<div><slot></slot></div>'
    }
  }
});

new Vue({
  el: '#app'
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
  <component-a>
    <div>Hello</div>
  </component-a>
</div>

Upvotes: 1

Thomas Brd
Thomas Brd

Reputation: 1273

You need to register component-a and component-b to your Vue instance if you want to call them globally.

The local instanciation of component-b (in component-a) is never called in the component-a's template.

So do something like this, it will solve your problem:

const app = new Vue({
    el: '#app'
});

Vue.component({
    'component-a': {
         template: '<div><span>Hi</span><slot></slot></div>',
    },
    'component-b': {
        template: '<div>Hello</div>',
    }
});

Upvotes: 0

Related Questions