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,999
  • 3
  • 16
  • 28
Matt Fellows
  • 6,512
  • 4
  • 35
  • 57

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>
tony19
  • 125,647
  • 18
  • 229
  • 307
Husam Ibrahim
  • 6,999
  • 3
  • 16
  • 28