- Menu 导航菜单
- 何时使用
- 代码演示
- 顶部导航
- 内嵌菜单
- 缩起内嵌菜单
- 只展开当前父级菜单
- 垂直菜单
- 主题
- 切换菜单类型
- 单文件递归菜单
- API
- Menu
- Menu 事件
- Menu.Item
- Menu.SubMenu
- SubMenu 事件
- Menu.ItemGroup
- Menu.Divider
Menu 导航菜单
为页面和功能提供导航的菜单列表。
何时使用
导航菜单是一个网站的灵魂,用户依赖导航在各个页面中进行跳转。一般分为顶部导航和侧边导航,顶部导航提供全局性的类目和功能,侧边导航提供多级结构来收纳和排列网站架构。
代码演示

顶部导航
水平的顶部导航菜单。
<template><div><a-menu v-model="current" mode="horizontal"><a-menu-item key="mail"> <a-icon type="mail" />Navigation One </a-menu-item><a-menu-item key="app" disabled> <a-icon type="appstore" />Navigation Two </a-menu-item><a-sub-menu><span slot="title" class="submenu-title-wrapper"><a-icon type="setting" />Navigation Three - Submenu</span><a-menu-item-group title="Item 1"><a-menu-item key="setting:1">Option 1</a-menu-item><a-menu-item key="setting:2">Option 2</a-menu-item></a-menu-item-group><a-menu-item-group title="Item 2"><a-menu-item key="setting:3">Option 3</a-menu-item><a-menu-item key="setting:4">Option 4</a-menu-item></a-menu-item-group></a-sub-menu><a-menu-item key="alipay"><a href="https://antdv.com" target="_blank" rel="noopener noreferrer">Navigation Four - Link</a></a-menu-item></a-menu></div></template><script>export default {data() {return {current: ['mail'],};},};</script>

内嵌菜单
垂直菜单,子菜单内嵌在菜单区域。
<template><div><a-menu@click="handleClick"style="width: 256px":defaultSelectedKeys="['1']":openKeys.sync="openKeys"mode="inline"><a-sub-menu key="sub1" @titleClick="titleClick"><span slot="title"><a-icon type="mail" /><span>Navigation One</span></span><a-menu-item-group key="g1"><template slot="title"><a-icon type="qq" /><span>Item 1</span></template><a-menu-item key="1">Option 1</a-menu-item><a-menu-item key="2">Option 2</a-menu-item></a-menu-item-group><a-menu-item-group key="g2" title="Item 2"><a-menu-item key="3">Option 3</a-menu-item><a-menu-item key="4">Option 4</a-menu-item></a-menu-item-group></a-sub-menu><a-sub-menu key="sub2" @titleClick="titleClick"><span slot="title"><a-icon type="appstore" /><span>Navigation Two</span></span><a-menu-item key="5">Option 5</a-menu-item><a-menu-item key="6">Option 6</a-menu-item><a-sub-menu key="sub3" title="Submenu"><a-menu-item key="7">Option 7</a-menu-item><a-menu-item key="8">Option 8</a-menu-item></a-sub-menu></a-sub-menu><a-sub-menu key="sub4"><span slot="title"><a-icon type="setting" /><span>Navigation Three</span></span><a-menu-item key="9">Option 9</a-menu-item><a-menu-item key="10">Option 10</a-menu-item><a-menu-item key="11">Option 11</a-menu-item><a-menu-item key="12">Option 12</a-menu-item></a-sub-menu></a-menu></div></template><script>export default {data() {return {current: ['mail'],openKeys: ['sub1'],};},methods: {handleClick(e) {console.log('click', e);},titleClick(e) {console.log('titleClick', e);},},watch: {openKeys(val) {console.log('openKeys', val);},},};</script>

缩起内嵌菜单
内嵌菜单可以被缩起/展开。
<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="['sub1']"mode="inline"theme="dark":inlineCollapsed="collapsed"><a-menu-item key="1"><a-icon type="pie-chart" /><span>Option 1</span></a-menu-item><a-menu-item key="2"><a-icon type="desktop" /><span>Option 2</span></a-menu-item><a-menu-item key="3"><a-icon type="inbox" /><span>Option 3</span></a-menu-item><a-sub-menu key="sub1"><span slot="title"><a-icon type="mail" /><span>Navigation One</span></span><a-menu-item key="5">Option 5</a-menu-item><a-menu-item key="6">Option 6</a-menu-item><a-menu-item key="7">Option 7</a-menu-item><a-menu-item key="8">Option 8</a-menu-item></a-sub-menu><a-sub-menu key="sub2"><span slot="title"><a-icon type="appstore" /><span>Navigation Two</span></span><a-menu-item key="9">Option 9</a-menu-item><a-menu-item key="10">Option 10</a-menu-item><a-sub-menu key="sub3" title="Submenu"><a-menu-item key="11">Option 11</a-menu-item><a-menu-item key="12">Option 12</a-menu-item></a-sub-menu></a-sub-menu></a-menu></div></template><script>export default {data() {return {collapsed: false,};},methods: {toggleCollapsed() {this.collapsed = !this.collapsed;},},};</script>

只展开当前父级菜单
点击菜单,收起其他展开的所有菜单,保持菜单聚焦简洁。
<template><div><a-menu mode="inline" :openKeys="openKeys" @openChange="onOpenChange" style="width: 256px"><a-sub-menu key="sub1"><span slot="title"><a-icon type="mail" /><span>Navigation One</span></span><a-menu-item key="1">Option 1</a-menu-item><a-menu-item key="2">Option 2</a-menu-item><a-menu-item key="3">Option 3</a-menu-item><a-menu-item key="4">Option 4</a-menu-item></a-sub-menu><a-sub-menu key="sub2"><span slot="title"><a-icon type="appstore" /><span>Navigation Two</span></span><a-menu-item key="5">Option 5</a-menu-item><a-menu-item key="6">Option 6</a-menu-item><a-sub-menu key="sub3" title="Submenu"><a-menu-item key="7">Option 7</a-menu-item><a-menu-item key="8">Option 8</a-menu-item></a-sub-menu></a-sub-menu><a-sub-menu key="sub4"><span slot="title"><a-icon type="setting" /><span>Navigation Three</span></span><a-menu-item key="9">Option 9</a-menu-item><a-menu-item key="10">Option 10</a-menu-item><a-menu-item key="11">Option 11</a-menu-item><a-menu-item key="12">Option 12</a-menu-item></a-sub-menu></a-menu></div></template><script>export default {data() {return {rootSubmenuKeys: ['sub1', 'sub2', 'sub4'],openKeys: ['sub1'],};},methods: {onOpenChange(openKeys) {const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1);if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {this.openKeys = openKeys;} else {this.openKeys = latestOpenKey ? [latestOpenKey] : [];}},},};</script>

垂直菜单
子菜单是弹出的形式。
<template><div><a-menu style="width: 256px" mode="vertical" @click="handleClick"><a-menu-item key="1"><a-icon type="mail" />Navigation One</a-menu-item><a-menu-item key="2"><a-icon type="calendar" />Navigation Two</a-menu-item><a-sub-menu key="sub1"><span slot="title"><a-icon type="appstore" /><span>Navigation Three</span></span><a-menu-item key="3">Option 3</a-menu-item><a-menu-item key="4">Option 4</a-menu-item><a-sub-menu key="sub1-2" title="Submenu"><a-menu-item key="5">Option 5</a-menu-item><a-menu-item key="6">Option 6</a-menu-item></a-sub-menu></a-sub-menu><a-sub-menu key="sub2"><span slot="title"><a-icon type="setting" /><span>Navigation Four</span></span><a-menu-item key="7">Option 7</a-menu-item><a-menu-item key="8">Option 8</a-menu-item><a-menu-item key="9">Option 9</a-menu-item><a-menu-item key="10">Option 10</a-menu-item></a-sub-menu></a-menu></div></template><script>export default {methods: {handleClick(e) {console.log('click ', e);},},};</script>

主题
内建了两套主题 light|dark,默认 light。
<template><div><a-switchdefaultChecked@change="changeTheme"checkedChildren="dark"unCheckedChildren="light"/><br /><br /><a-menustyle="width: 256px":defaultSelectedKeys="['1']":defaultOpenKeys="['sub1']"mode="inline":theme="theme":selectedKeys="[current]"@click="handleClick"><a-menu-item key="1"><a-icon type="mail" />Navigation One</a-menu-item><a-menu-item key="2"><a-icon type="calendar" />Navigation Two</a-menu-item><a-sub-menu key="sub1"><span slot="title"><a-icon type="appstore" /><span>Navigation Three</span></span><a-menu-item key="3">Option 3</a-menu-item><a-menu-item key="4">Option 4</a-menu-item><a-sub-menu key="sub1-2" title="Submenu"><a-menu-item key="5">Option 5</a-menu-item><a-menu-item key="6">Option 6</a-menu-item></a-sub-menu></a-sub-menu><a-sub-menu key="sub2"><span slot="title"><a-icon type="setting" /><span>Navigation Four</span></span><a-menu-item key="7">Option 7</a-menu-item><a-menu-item key="8">Option 8</a-menu-item><a-menu-item key="9">Option 9</a-menu-item><a-menu-item key="10">Option 10</a-menu-item></a-sub-menu></a-menu></div></template><script>export default {data() {return {current: '1',theme: 'dark',};},methods: {handleClick(e) {console.log('click ', e);this.current = e.key;},changeTheme(checked) {this.theme = checked ? 'dark' : 'light';},},};</script>

切换菜单类型
展示动态切换模式。
<template><div><a-switch :defaultChecked="false" @change="changeMode" /> Change Mode<span className="ant-divider" style="margin: 0 1em" /><a-switch :defaultChecked="false" @change="changeTheme" /> Change Theme<br /><br /><a-menustyle="width: 256px":defaultSelectedKeys="['1']":defaultOpenKeys="['sub1']":mode="mode":theme="theme"><a-menu-item key="1"><a-icon type="mail" />Navigation One</a-menu-item><a-menu-item key="2"><a-icon type="calendar" />Navigation Two</a-menu-item><a-sub-menu key="sub1"><span slot="title"><a-icon type="appstore" /><span>Navigation Three</span></span><a-menu-item key="3">Option 3</a-menu-item><a-menu-item key="4">Option 4</a-menu-item><a-sub-menu key="sub1-2" title="Submenu"><a-menu-item key="5">Option 5</a-menu-item><a-menu-item key="6">Option 6</a-menu-item></a-sub-menu></a-sub-menu><a-sub-menu key="sub2"><span slot="title"><a-icon type="setting" /><span>Navigation Four</span></span><a-menu-item key="7">Option 7</a-menu-item><a-menu-item key="8">Option 8</a-menu-item><a-menu-item key="9">Option 9</a-menu-item><a-menu-item key="10">Option 10</a-menu-item></a-sub-menu></a-menu></div></template><script>export default {data() {return {mode: 'inline',theme: 'light',};},methods: {changeMode(checked) {this.mode = checked ? 'vertical' : 'inline';},changeTheme(checked) {this.theme = checked ? 'dark' : 'light';},},};</script>

单文件递归菜单
使用单文件方式递归生成菜单。因组件内部会动态更改a-sub-menu的属性,如果拆分成单文件,无法将属性挂载到a-sub-menu上,你需要自行声明属性并挂载。为了方便,避免属性的声明,我们推荐使用函数式组件。
<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 SubMenu.vue https://github.com/vueComponent/ant-design-vue/blob/master/components/menu/demo/SubMenu.vue* SubMenu1.vue https://github.com/vueComponent/ant-design-vue/blob/master/components/menu/demo/SubMenu1.vue* */import SubMenu from './SubMenu';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>
API
<template>
<a-menu>
<a-menu-item>菜单项</a-menu-item>
<a-sub-menu title="子菜单">
<a-menu-item>子菜单项</a-menu-item>
</a-sub-menu>
</a-menu>
</template>
Menu
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| defaultOpenKeys | 初始展开的 SubMenu 菜单项 key 数组 | ||
| defaultSelectedKeys | 初始选中的菜单项 key 数组 | string[] | |
| forceSubMenuRender | 在子菜单展示之前就渲染进 DOM | boolean | false |
| inlineCollapsed | inline 时菜单是否收起状态 | boolean | - |
| inlineIndent | inline 模式的菜单缩进宽度 | number | 24 |
| mode | 菜单类型,现在支持垂直、水平、和内嵌模式三种 | string: vertical vertical-right horizontal inline | vertical |
| multiple | 是否允许多选 | boolean | false |
| openKeys(.sync) | 当前展开的 SubMenu 菜单项 key 数组 | string[] | |
| selectable | 是否允许选中 | boolean | true |
| selectedKeys(v-model) | 当前选中的菜单项 key 数组 | string[] | |
| subMenuCloseDelay | 用户鼠标离开子菜单后关闭延时,单位:秒 | number | 0.1 |
| subMenuOpenDelay | 用户鼠标进入子菜单后开启延时,单位:秒 | number | 0 |
| theme | 主题颜色 | string: light dark | light |
| overflowedIndicator | 自定义 Menu 折叠时的图标 | DOM | <span>···</span> |
Menu 事件
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| click | 点击 MenuItem 调用此函数 | function({ item, key, keyPath }) |
| deselect | 取消选中时调用,仅在 multiple 生效 | function({ item, key, selectedKeys }) |
| openChange | SubMenu 展开/关闭的回调 | function(openKeys: string[]) |
| select | 被选中时调用 | function({ item, key, selectedKeys }) |
Menu.Item
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| disabled | 是否禁用 | boolean | false |
| key | item 的唯一标志 | string | |
| title | 设置收缩时展示的悬浮标题 | string |
Menu.SubMenu
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| disabled | 是否禁用 | boolean | false |
| key | 唯一标志 | string | |
| title | 子菜单项值 | string|slot |
Menu.SubMenu 的子元素必须是 MenuItem 或者 SubMenu.
SubMenu 事件
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| titleClick | 点击子菜单标题 | ({ key, domEvent }) |
Menu.ItemGroup
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| title | 分组标题 | string||function|slot |
Menu.ItemGroup 的子元素必须是 MenuItem.
Menu.Divider
菜单项分割线,只用在弹出菜单内。
