AntDesign vue学习笔记(五)导航菜单动态加载
一、使用官方例子
<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>
本博客是个人工作中记录,更深层次的问题可以提供有偿技术支持。
另外建了几个QQ技术群:
2、全栈技术群:616945527
2、硬件嵌入式开发: 75764412
3、Go语言交流群:9924600
闲置域名WWW.EXAI.CN (超级人工智能)出售。
另外建了几个QQ技术群:
2、全栈技术群:616945527
2、硬件嵌入式开发: 75764412
3、Go语言交流群:9924600
闲置域名WWW.EXAI.CN (超级人工智能)出售。