2

I'm attempting to create components using Vue, so that I can remove a lot of duplicated HTML in a site I'm working on.

I have a <ym-menucontent> component, which within it will eventually have several other components, conditionally rendered.

While doing this I've hit a wall and so have simplified everything to get to the root of the problem.

When rendering the ym-menucontent component the first sub-component is the only one which gets rendered and I can't work out why or how to get around it...

<template id="menucontent">
    <div>
        <ym-categories :menuitem="menuitem"/>
        <ym-rootmaps :menuitem="menuitem"/>
        <p>1: {{menuitem.rootMapsTab}}</p>
        <p>2: {{menuitem.exploreTab}}</p>
    </div>
</template>

<template id="rootmaps">
    <div>Root Maps</div>
</template>

<template id="categories">
    <div>Categories</div>
</template>

app.js

Vue.component('ym-menucontent', {
    template: '#menucontent',
    props: ['menuitem'],
    data: function() {
        return {
            customMenu: window.customMenuJSON
        }
    }
});
Vue.component('ym-rootmaps', {
    template: '#rootmaps',
    props: ['menuitem'],
    data: function() {
        return {
            customMenu: window.customMenuJSON,
            rootMaps: window.rootAreas
        }
    }
});
Vue.component('ym-categories', {
    template: '#categories',
    props: ['menuitem'],
    data: function() {
        return {
            customMenu: window.customMenuJSON,
            rootMaps: window.rootAreas
        }
    }
});

usage...

<div 
    v-for="mi in customMenu.topLevelMenuItems"
    :id="mi.name" 
    class="page-content tab swiper-slide">
         <ym-menucontent :menuitem="mi"/>
</div>

Output

<div>Categories</div>

if I switch around ym-cateogries and ym-rootmaps then the output becomes...

<div>Root Maps</div>

if I remove both then I see...

<p>1: true</p>
<p>2:</p>

I'd expect to see a combination of all of them...

<div>Categories</div>
<div>Root Maps</div>
<p>1: true</p>
<p>2:</p>
Husam Ibrahim
  • 6,509
  • 1
  • 14
  • 26
Matt Fellows
  • 6,462
  • 4
  • 33
  • 55

1 Answers1

3

This is probably because you're using self-closing components in DOM templates, which is recommended against in the style-guide ..

Unfortunately, HTML doesn’t allow custom elements to be self-closing - only official “void” elements. That’s why the strategy is only possible when Vue’s template compiler can reach the template before the DOM, then serve the DOM spec-compliant HTML.

This should work for you ..

<template id="menucontent">
    <div>
        <ym-categories :menuitem="menuitem"></ym-categories>
        <ym-rootmaps :menuitem="menuitem"></ym-rootmaps>
        <p>1: {{menuitem.rootMapsTab}}</p>
        <p>2: {{menuitem.exploreTab}}</p>
    </div>
</template>

<div 
    v-for="mi in customMenu.topLevelMenuItems"
    :id="mi.name" 
    class="page-content tab swiper-slide">
         <ym-menucontent :menuitem="mi"></ym-menucontent>
</div>
Husam Ibrahim
  • 6,509
  • 1
  • 14
  • 26