一、使用官方例子
<template> <div style="width: 256px"> <a-button type="primary" @click="toggleCollapsed" style="margin-bottom: 16px"> <a-icon :type="collapsed ? 'menu-unfold' : 'menu-fold'" /> </a-button> <a-menu :defaultSelectedKeys="['1']" :defaultOpenKeys="['2']" mode="inline" theme="dark" :inlineCollapsed="collapsed" > <template v-for="item in list"> <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 :menu-info="item" :key="item.key" /> </template> </a-menu> </div> </template> <script> // recommend use functional component // <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> // export default { // props: ['menuInfo'], // }; import { Menu } from 'ant-design-vue'; const SubMenu = { template: ` <a-sub-menu :key="menuInfo.key" v-bind="$props" v-on="$listeners"> <span slot="title"> <a-icon type="mail" /><span>{{ menuInfo.title }}</span> </span> <template v-for="item in 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> `, name: 'SubMenu', // must add isSubMenu: true isSubMenu: true, props: { ...Menu.SubMenu.props, // Cannot overlap with properties within Menu.SubMenu.props menuInfo: { type: Object, default: () => ({}), }, }, }; export default { components: { 'sub-menu': SubMenu, }, data() { return { collapsed: false, list: [ { key: '1', title: 'Option 1', }, { key: '2', title: 'Navigation 2', children: [ { key: '2.1', title: 'Navigation 3', children: [{ key: '2.1.1', title: 'Option 2.1.1' }], }, ], }, ], }; }, methods: { toggleCollapsed() { this.collapsed = !this.collapsed; }, }, }; </script>
增加@click事件
點擊彈出效果如下圖,注意:這里@click后不能直接寫@click="alert('a')",會報TypeError: _vm.alert is not a function
二、其他實現方法
一般的后台系統都有一個樹形導航菜單,具體實現如下,主要參考
https://my.oschina.net/u/4131669/blog/3048416
menuList: [
{
'name': '首頁',
'url': 'http://192.168.1.100:9999',
'iconType': 'laptop',
'sidebars': []
},
{
'name': '企業信息',
'url': null,
'iconType': 'bars',
'sidebars': [
{
'name': '公司管理',
'url': 'http://192.168.1.100:8890//swagger-ui.html',
'iconType': 'laptop',
'sidebars': []
}
]
},
{
'name': '工程管理',
'url': 'http://192.168.1.100:9999/about',
'iconType': 'laptop',
'sidebars': []
}
]
}
1、定義sub-menu組件,用於遞歸顯示多級菜單
<template functional> <a-sub-menu :key="props.menuInfo.name" > <span slot="title"> <a-icon type="folder" /> <span>{{ props.menuInfo.name +','+props.menuInfo.sidebars.length}}</span> </span> <template v-for="item in props.menuInfo.sidebars"> <a-menu-item v-if="!item.sidebars.length" :key="item.key"> <span>{{ item.name }}</span> </a-menu-item> </template> </a-sub-menu> </template> <script> export default { name: 'SubMenu', props: ['menuInfo'] }
不能在函數式組件里定義事件並通過@click掉用,但是可以調用父組件的事件,方法
<template functional> <a-sub-menu :key="props.menuInfo.name" @click=parent.fetchMenu()>
...
原因是:
函數式組件沒有實例,事件只能由父組件傳遞。
template functional標志該組件為函數化組件
2、在Mainfrm中引入組件
import SubMenu from './SubMenu'
components: {
SubMenu
}
3、menu模板
<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>
6、最終實現效果如下
地址: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>