如何使用vue.js制作条件多级菜单?

时间:2018-12-02 05:19:42

标签: vue.js vuejs2

####################### EDIT #################### #####

根据@Criss的回答,该方法无效,因为子项与父项不同。

enter image description here

一个没有孩子的简单物品应如下所示:

<li class="sidebar-item">
    <a class="sidebar-link" href="/test.html">
        <span class="align-middle">Test</span>
    </a>
</li>

当一个项目有一个孩子时,它应该具有选项 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>

没有更多子项的子项应如下所示:

<li class="sidebar-item">
    <a class="sidebar-link" href="/test3.html">Test3</a>
</li>

我根据@Criss的回应进行的新尝试如下:

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>

但是子项目仍在消失。


#######################问题################## #####

我尝试制作一个多级菜单

在vue.js中,我仅获得第一级。我不知道如何进行所有级别的循环,以及如何处理固定物品或带孩子物品的情况。

我正在尝试这样做:

->移至以上版本<-

我有这个多维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":""}}

我想做这样的事情:

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>

有人可以帮助我如何进行其他级别的工作吗?

1 个答案:

答案 0 :(得分:1)

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>

这通过使用递归进行工作-您定义一个包含其自己的链接和所有子链接的组件,并且v-if="menuitem.child"存在,然后该组件创建其自身的子副本。

这种方法的妙处在于,您不再关心子项目的嵌套深度。

您应该调整样式...