一般的后台系统都有一个树形导航菜单,具体实现如下,主要参考
https://my.oschina.net/u/4131669/blog/3048416
"menuList": [ { "name": "首页", "url": "http://192.168.1.100:9999", "iconType": "laptop", }, { "name": "企业信息", "url": null, "iconType": "bars", "sidebars": [ { "name": "公司管理", "url": "http://192.168.1.100:8890//swagger-ui.html", "iconType": "italic", "children": [] } ] }, { "name": "工程管理", "url": "http://192.168.1.100:9999/about", "iconType": "info", } ]
1、定义sub-menu组件,用于递归显示多级菜单
<template functional> <a-sub-menu :key="props.menuInfo.key" > <span slot="title"> <a-icon type="mail" /><span>{{ props.menuInfo.title }}</span> </span> <template v-for="item in props.menuInfo.children"> <a-menu-item v-if="!item.children" :key="item.key" > <a-icon type="pie-chart" /> <span>{{ item.title }}</span> </a-menu-item> <sub-menu v-else :key="item.key" :menu-info="item" /> </template> </a-sub-menu> </template> <script> export default { props: ['menuInfo'], }; </script>
template functional标志该组件为函数化组件
2、在Mainfrm中引入组件
import SubMenu from './SubMenu'
components: {
SubMenu
}
3、menu模板
4、axios获取并显示实现代码
<template v-for="item in menuList"> <a-menu-item v-if="!item.sidebars.length" :key="item.name"> <a-icon :type="item.iconType" /> <span>{{item.name}}</span> </a-menu-item> <sub-menu v-else :menu-info="item" :key="item.name"/> </template>
getmenu () { let that = this this.axios( { method:"get", url:'/api/getmenu', headers: { 'Content-Type':'application/json;charset=UTF-8' } }) .then((response) => { this.menus=response.data.data; console.log(response) }) .catch(function (error) { console.log(error) }) },
5、menus在data中定义
data () { return { menus:[] } },
6、最终实现效果如下(加了一些菜单和修改了一些图标和定义的有点不一样)
总结:使用过程中碰到一个问题就是这个子组件里写@click事件比如@click="alert('a')"不起作用,还报错 _vm.alert is not a function,暂时没搞明白原因,如果使用最高替换成<a>标签。
地址:https://www.jianshu.com/p/c549c3d0f595这篇文章的递归方法点击事件显示是正常的,他这个用的是原生html元素,需要美化界面,代码如下
list: [ { "id": "1", "menuName": "项目管理", "childTree": [{ "menuName": "项目进度", "childTree": [{ "menuName": "项目一", "childTree": [{ "menuName": "详细信息" }] }] }, { "menuName": "任务安排" }] }, { "id": "2", "menuName": "数据统计" }, { "id": "3", "menuName": "人员管理" }]
// 子组件代码 <template> <li> <span @click="toggle"> {{ model.menuName }} </span> <ul v-if="isFolder" v-show="open"> <items v-for="(item, index) in model.childTree" :model="item" :key="index"></items> </ul> </li> </template> <script type="text/javascript"> export default { // 组件递归必要条件,name属性 name: 'items', props: ['model'], data() { return { // 控制子列表的显示隐藏 open: false } }, computed: { // 是否还有子列表需要渲染,作为v-if的判断条件 isFolder() { return this.model.childTree && this.model.childTree.length } }, methods: { // 切换列表显示隐藏的方法 toggle() { if(this.isFolder) { this.open = !this.open } }, } } </script>
<template> <div> <ul> <items v-for="(model, index) in list" :model="model" :key="index"></items> </ul> </div> </template> <script type="text/javascript"> components: { Items }, data() { return { list: ... } } </script>