0

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?

2 Answers 2

1

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>

Sign up to request clarification or add additional context in comments.

2 Comments

One more question is that can I add some restriction in registration of component-b that it must be children of component-a? like: Vue.component('component-b', { template: '<div>Hello</div>', parent: 'component-a' });
Hm... unfortunatelly, no, Vue still doesn't support that. The closest it gets to that is registering it locally, but, as we found out, If we do that, we can't use component-b in the root, not even if it is inside a <slot>...
0

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>',
    }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.