Reputation: 267
According to @Criss's answer, the method did not work, because the child item is different from the parent item.
A simple item without child should look like this:
<li class="sidebar-item">
<a class="sidebar-link" href="/test.html">
<span class="align-middle">Test</span>
</a>
</li>
When an item has a child it should have the option data-toggle="collapse"
<li class="sidebar-item">
<a class="sidebar-link" href="/test.html" data-toggle="collapse" >
<span class="align-middle">Test</span>
</a>
<ul class="sidebar-dropdown list-unstyled collapse">
##<li>#### CHILD ITENS ####</li>##
</ul>
</li>
And the subitems when they do not have more childs should look like this:
<li class="sidebar-item">
<a class="sidebar-link" href="/test3.html">Test3</a>
</li>
my new attempt based on @Criss's response, went like this:
Vue.component('menu-item', {
props: ['cmitens'],
template: '#menu-item'
});
new Vue({el: '#vuesadminmenu',
data: {
menuitens: {"test0":{"titulo":"Test0","open":"false","selected":"false","link":"http:\/\/www.link.com\/test0","child":""},"test1":{"titulo":"Test1","open":"true","selected":"false","link":"http:\/\/www.link.com\/test1","child":{"test2":{"titulo":"Test2","open":"true","selected":"false","link":"http:\/\/www.link.com\/test2","child":{"test3":{"titulo":"Test3","open":"true","selected":"true","link":"http:\/\/www.link.com\/test3","child":""}}},"test4":{"titulo":"Test4","open":"false","selected":"false","link":"http:\/\/www.link.com\/test4","child":""}}},"test5":{"titulo":"Test5","open":"false","selected":"false","link":"http:\/\/www.link.com\/test5","child":{"test6":{"titulo":"Test6","open":"false","selected":"false","link":"http:\/\/www.link.com\/test6","child":""}}},"test7":{"titulo":"Test7","open":"false","selected":"false","link":"http:\/\/www.link.com\/test7","child":""}}
}
});
ol ol, ol ul, ul ol, ul ul { margin-left: 20px; }
<script src="https://appstack.bootlab.io/js/app.js"></script>
<link href="https://appstack.bootlab.io/css/app.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div class="wrapper">
<nav class="sidebar">
<div class="sidebar-content">
<ul id="vuesadminmenu" class="sidebar-nav">
<template id="menu-item">
<li class="sidebar-item" v-for="(mitem, mkey) in menuitens" v-bind:class="[(mitem.open == 'true') ? 'active' : '']">
<a class="sidebar-link" v-bind:href="mitem.child !== '' ? '#'+mkey : mitem.link" :data-toggle="[(mitem.child !== '') ? 'collapse' : '']" v-bind:class="[(mitem.open == 'true') ? '' : 'collapsed']">
<span class="align-middle">{{mitem.titulo}} {{mitem.open}}</span>
</a>
<ul class="sidebar-dropdown list-unstyled collapse" v-if="mitem.child !== ''" v-bind:class="[(mitem.open == 'true') ? 'show' : '']">
<menu-item :cmitens="mitem.child"></menu-item>
</ul>
</li>
</template>
</ul>
</div>
</nav>
</div>
But the subitems are still disappearing.
I try to make a multilevel menu
In vue.js I only get the first level. I have no idea how to do the loop for all levels, and treat the conditions of when it is a fixed item or item with child.
I'm trying to do so:
--> moved to the above edition <--
I have this multidimensional json
{"test0":{"titulo":"Test0","open":"false","selected":"false","link":"\/test0.html","child":""},
"test1":{"titulo":"Test1","open":"false","selected":"false","link":"\/test1.html"","child":{
"test2":{"titulo":"Test2","open":"false","selected":"false","link":"\/test2.html"","child":{
"test3":{"titulo":"Test3","open":"false","selected":"false","link":"\/test3.html"","child":""}}},
"test4":{"titulo":"Test4","open":"false","selected":"false","link":"\/test4.html"","child":""}}},
"test5":{"titulo":"Test5","open":"false","selected":"false","link":"\/test5.html"","child":{
"test6":{"titulo":"Test6","open":"false","selected":"false","link":"\/test6.html"","child":""}}},
"test7":{"titulo":"Test7","open":"false","selected":"false","link":"\/test7.html"","child":""}}
I'd like to do something like this:
ol ol, ol ul, ul ol, ul ul {
margin-left: 20px;
}
<script src="https://appstack.bootlab.io/js/app.js"></script>
<link href="https://appstack.bootlab.io/css/app.css" rel="stylesheet"/>
<div class="wrapper">
<nav class="sidebar">
<div class="sidebar-content">
<ul class="sidebar-nav">
<li class="sidebar-item">
<a class="sidebar-link" href="/test0.html">
<span class="align-middle">Test0</span>
</a>
</li>
<li class="sidebar-item active">
<a href="/test1.html" data-toggle="collapse" class="sidebar-link">
<i class="align-middle" data-feather="layout"></i> <span class="align-middle">Test1</span>
</a>
<ul class="sidebar-dropdown list-unstyled collapse show">
<li class="sidebar-item active">
<a href="/test2.html" data-toggle="collapse" class="sidebar-link">
<i class="align-middle" data-feather="layout"></i> <span class="align-middle">Test2</span>
</a>
<ul class="sidebar-dropdown list-unstyled collapse show">
<li class="sidebar-item">
<a class="sidebar-link" href="/test3.html">Test3</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="sidebar-item">
<a class="sidebar-link" href="/test4.html">
<span class="align-middle">Test4</span>
</a>
</li>
</ul>
</div>
</nav>
</div>
Can someone help me how can I do the other levels??
Upvotes: 0
Views: 3504
Reputation: 983
Vue.component('menu-item', {
props: ['menuitens'],
template: '<ul class="sidebar-nav">'+
'<li class="sidebar-item" v-for="(mitem, mkey) in menuitens" v-bind:class="[(mitem.open == \'true\') ? \'active\' : \'\']">'+
'<a class="sidebar-link" v-bind:href="mitem.link">'+
'<span class="align-middle">{{mitem.titulo}} {{mitem.open}}</span>'+
'</a>'+
'<menu-item v-if="mitem.child !== \'\'" :menuitens="mitem.child"></menu-item>'+
'</li>'+
'</ul>'
});
new Vue({el: '#vuesadminmenu',
data: {
menuitens: {"test0":{"titulo":"Test0","open":"false","selected":"false","link":"http:\/\/www.link.com\/test0","child":""},"test1":{"titulo":"Test1","open":"true","selected":"false","link":"http:\/\/www.link.com\/test1","child":{"test2":{"titulo":"Test2","open":"true","selected":"false","link":"http:\/\/www.link.com\/test2","child":{"test3":{"titulo":"Test3","open":"true","selected":"true","link":"http:\/\/www.link.com\/test3","child":""}}},"test4":{"titulo":"Test4","open":"false","selected":"false","link":"http:\/\/www.link.com\/test4","child":""}}},"test5":{"titulo":"Test5","open":"false","selected":"false","link":"http:\/\/www.link.com\/test5","child":{"test6":{"titulo":"Test6","open":"false","selected":"false","link":"http:\/\/www.link.com\/test6","child":""}}},"test7":{"titulo":"Test7","open":"false","selected":"false","link":"http:\/\/www.link.com\/test7","child":""}}
}
});
ol ol, ol ul, ul ol, ul ul { margin-left: 20px; }
ul {
padding-bottom: 0 !important;
}
<script src="https://appstack.bootlab.io/js/app.js"></script>
<link href="https://appstack.bootlab.io/css/app.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div class="wrapper">
<nav class="sidebar">
<div class="sidebar-content" id="vuesadminmenu">
<menu-item :menuitens="menuitens"></menu-item>
</div>
</nav>
</div>
This works by using recursion - you define a component that holds it's own link and all child links and v-if="menuitem.child"
exists, then the component creates a sub-copy of itself.
The beautiful thing about this approach is that you no longer care how deeply nested the child items are.
You should tweak the styling tho...
Upvotes: 2