最近在写框架,开发主页面的时候布局采用的是左侧菜单栏的形式,因为没有现成的轮子与使用技术栈的原因,选择使用elementui的navmenu控件进行改造,实现多层级的菜单栏展现样式,先上个效果图
因为是使用asp.net mvc5进行的开发,所以不可能使用webpackge纯前端的方式使用vue单文件的形式造轮子,所以经过搜索,决定使用x-template类型的脚本文件作为模板载体进行二次封装,首先分析下navmenu的结构,最底层的无孩子节点的菜单使用el-menu-item标签标识,有孩子节点的菜单使用el-submenu标签进行嵌套,template标签显示该层级的菜单名称,所以我们需要对el-menu-item这个标签进行递归判断,上一波代码
1.模板
代码语言:javascript复制<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.调用
代码语言:javascript复制 <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.注册组件与初始化数据
代码语言:javascript复制<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方法获取内容,可参考如下代码
代码语言:javascript复制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