最近在写框架,开发主页面的时候布局采用的是左侧菜单栏的形式,因为没有现成的轮子与使用技术栈的原因,选择使用elementui的navmenu控件进行改造,实现多层级的菜单栏展现样式,先上个效果图

因为是使用asp.net mvc5进行的开发,所以不可能使用webpackge纯前端的方式使用vue单文件的形式造轮子,所以经过搜索,决定使用x-template类型的脚本文件作为模板载体进行二次封装,首先分析下navmenu的结构,最底层的无孩子节点的菜单使用el-menu-item标签标识,有孩子节点的菜单使用el-submenu标签进行嵌套,template标签显示该层级的菜单名称,所以我们需要对el-menu-item这个标签进行递归判断,上一波代码

1.模板

<script type="text/x-template" id="main-template">
    <div>
        <el-menu-item v-if="itemData.nodes==null" :index="itemData.index">
            <span>{{itemData.text}}</span>
        </el-menu-item>

        <el-submenu v-if="itemData.nodes!=null" :index="itemData.index">
            <template slot="title">
                <span>{{itemData.text}}</span>
            </template>
            <!--调用组件自身,循环item的nodes,实现递归 -->
            <child v-for="item in itemData.nodes" :item-data="item"></child>
        </el-submenu>
    </div>

</script>

2.调用

 <div id="app">
        <el-col span="4">
            <el-menu background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" id="menu">
                <child v-for="item in itemlist" :item-data="item"></child>
            </el-menu>

        </el-col>

    </div>

3.注册组件与初始化数据

<script>
    // 注册
    Vue.component('child', {
        props: ['itemData'],
        // 同样也可以在 vm 实例中像 “this.message” 这样使用
        template: '#main-template'
    })
    // 创建根实例
    new Vue({
        el: '#app',
        data: {
            itemlist: [{
                "mouduleurl": "",
                "text": "后台管理",
                "value": "0001",
                "index": "1",
                "nodes": [{
                    "mouduleurl": "pages/config/config_list.html",
                    "text": "系统参数",
                    "value": "00010001",
                    "index": "1-1",
                }, {
                    "mouduleurl": "pages/dmp/table_list.html",
                    "text": "数据表结构",
                    "value": "00010002",
                    "index": "1-2",
                    "nodes": [{
                        "mouduleurl": "pages/config/config_list.html",
                        "text": "数据表关联管理",
                        "value": "00010002001",
                        "index": "1-2-1",
                    }]
                }, {
                    "mouduleurl": "pages/module/module_settinglist.html",
                    "text": "模块地址",
                    "value": "00010003",
                    "index": "1-3",
                }],

            }, {
                "mouduleurl": "",
                "text": "文章管理",
                "value": "0002",
                "index": "2",
                "nodes": [{
                    "mouduleurl": "pages/article/article_list.html",
                    "text": "文章列表",
                    "value": "00020001",
                    "index": "2-1",
                }],

            }, {
                "mouduleurl": "",
                "text": "爬虫专题",
                "value": "0003",
                "index": "3",
                "nodes": [{
                    "mouduleurl": "pages/spider/music/music_search.html",
                    "text": "网易云音乐",
                    "value": "00030001",
                    "index": "3-1",
                }],

            }, {
                "mouduleurl": "",
                "text": "测试4",
                "value": "0004",
                "index": "4",


            }]
        }
    })
</script>

注:

1.在不使用vue工程开发组件的时候,采用x-template类型的脚本声明模板,在注册的时候模板使用#+脚本的id进行调用

2.组件循环的原理就是在拥有nodes数据,即拥有孩子节点时,在模板中嵌套使用声明的组件

3.如果想将模板分离,可以将模板内容定义在一个html文件中,通过ajax的get方法获取内容,可参考如下代码

var treetemplatepath = applicaitoncontext + '/component/tree/fastdo-tree-template.html';
Vue.component('fastdo-tree', function (resolve, reject) {
    $.get(treetemplatepath).then(function (res) {
        resolve({
            template: res,
            //这边的参数名称,例如defaultExpandAll要与elementui中的保持一致,否则会不被识别
            props: ["data", "defaultProps", "defaultExpandAll"],
            methods: {
                handleNodeClick(data) {
                    //子组件调用父组件方法,node-click为绑定事件方法而非js函数名
                    this.$emit('node-click', data)
                }
            }
        })
    });
});

示例源码地址:vue多级菜单栏: vue+elementui实现多级菜单栏(x-template模板方式) - Gitee.com

Logo

前往低代码交流专区

更多推荐