Menu 导航菜单

为页面和功能提供导航的菜单列表。

何时使用

导航菜单是一个网站的灵魂,用户依赖导航在各个页面中进行跳转。一般分为顶部导航和侧边导航,顶部导航提供全局性的类目和功能,侧边导航提供多级结构来收纳和排列网站架构。

代码演示

Menu导航菜单 - 图1

顶部导航

水平的顶部导航菜单。

  1. <template>
  2. <div>
  3. <a-menu v-model="current" mode="horizontal">
  4. <a-menu-item key="mail"> <a-icon type="mail" />Navigation One </a-menu-item>
  5. <a-menu-item key="app" disabled> <a-icon type="appstore" />Navigation Two </a-menu-item>
  6. <a-sub-menu>
  7. <span slot="title" class="submenu-title-wrapper"
  8. ><a-icon type="setting" />Navigation Three - Submenu</span
  9. >
  10. <a-menu-item-group title="Item 1">
  11. <a-menu-item key="setting:1">
  12. Option 1
  13. </a-menu-item>
  14. <a-menu-item key="setting:2">
  15. Option 2
  16. </a-menu-item>
  17. </a-menu-item-group>
  18. <a-menu-item-group title="Item 2">
  19. <a-menu-item key="setting:3">
  20. Option 3
  21. </a-menu-item>
  22. <a-menu-item key="setting:4">
  23. Option 4
  24. </a-menu-item>
  25. </a-menu-item-group>
  26. </a-sub-menu>
  27. <a-menu-item key="alipay">
  28. <a href="https://antdv.com" target="_blank" rel="noopener noreferrer"
  29. >Navigation Four - Link</a
  30. >
  31. </a-menu-item>
  32. </a-menu>
  33. </div>
  34. </template>
  35. <script>
  36. export default {
  37. data() {
  38. return {
  39. current: ['mail'],
  40. };
  41. },
  42. };
  43. </script>

Menu导航菜单 - 图2

内嵌菜单

垂直菜单,子菜单内嵌在菜单区域。

  1. <template>
  2. <div>
  3. <a-menu
  4. style="width: 256px"
  5. :default-selected-keys="['1']"
  6. :open-keys.sync="openKeys"
  7. mode="inline"
  8. @click="handleClick"
  9. >
  10. <a-sub-menu key="sub1" @titleClick="titleClick">
  11. <span slot="title"><a-icon type="mail" /><span>Navigation One</span></span>
  12. <a-menu-item-group key="g1">
  13. <template slot="title"> <a-icon type="qq" /><span>Item 1</span> </template>
  14. <a-menu-item key="1">
  15. Option 1
  16. </a-menu-item>
  17. <a-menu-item key="2">
  18. Option 2
  19. </a-menu-item>
  20. </a-menu-item-group>
  21. <a-menu-item-group key="g2" title="Item 2">
  22. <a-menu-item key="3">
  23. Option 3
  24. </a-menu-item>
  25. <a-menu-item key="4">
  26. Option 4
  27. </a-menu-item>
  28. </a-menu-item-group>
  29. </a-sub-menu>
  30. <a-sub-menu key="sub2" @titleClick="titleClick">
  31. <span slot="title"><a-icon type="appstore" /><span>Navigation Two</span></span>
  32. <a-menu-item key="5">
  33. Option 5
  34. </a-menu-item>
  35. <a-menu-item key="6">
  36. Option 6
  37. </a-menu-item>
  38. <a-sub-menu key="sub3" title="Submenu">
  39. <a-menu-item key="7">
  40. Option 7
  41. </a-menu-item>
  42. <a-menu-item key="8">
  43. Option 8
  44. </a-menu-item>
  45. </a-sub-menu>
  46. </a-sub-menu>
  47. <a-sub-menu key="sub4">
  48. <span slot="title"><a-icon type="setting" /><span>Navigation Three</span></span>
  49. <a-menu-item key="9">
  50. Option 9
  51. </a-menu-item>
  52. <a-menu-item key="10">
  53. Option 10
  54. </a-menu-item>
  55. <a-menu-item key="11">
  56. Option 11
  57. </a-menu-item>
  58. <a-menu-item key="12">
  59. Option 12
  60. </a-menu-item>
  61. </a-sub-menu>
  62. </a-menu>
  63. </div>
  64. </template>
  65. <script>
  66. export default {
  67. data() {
  68. return {
  69. current: ['mail'],
  70. openKeys: ['sub1'],
  71. };
  72. },
  73. watch: {
  74. openKeys(val) {
  75. console.log('openKeys', val);
  76. },
  77. },
  78. methods: {
  79. handleClick(e) {
  80. console.log('click', e);
  81. },
  82. titleClick(e) {
  83. console.log('titleClick', e);
  84. },
  85. },
  86. };
  87. </script>

Menu导航菜单 - 图3

缩起内嵌菜单

内嵌菜单可以被缩起/展开。

  1. <template>
  2. <div style="width: 256px">
  3. <a-button type="primary" style="margin-bottom: 16px" @click="toggleCollapsed">
  4. <a-icon :type="collapsed ? 'menu-unfold' : 'menu-fold'" />
  5. </a-button>
  6. <a-menu
  7. :default-selected-keys="['1']"
  8. :default-open-keys="['sub1']"
  9. mode="inline"
  10. theme="dark"
  11. :inline-collapsed="collapsed"
  12. >
  13. <a-menu-item key="1">
  14. <a-icon type="pie-chart" />
  15. <span>Option 1</span>
  16. </a-menu-item>
  17. <a-menu-item key="2">
  18. <a-icon type="desktop" />
  19. <span>Option 2</span>
  20. </a-menu-item>
  21. <a-menu-item key="3">
  22. <a-icon type="inbox" />
  23. <span>Option 3</span>
  24. </a-menu-item>
  25. <a-sub-menu key="sub1">
  26. <span slot="title"><a-icon type="mail" /><span>Navigation One</span></span>
  27. <a-menu-item key="5">
  28. Option 5
  29. </a-menu-item>
  30. <a-menu-item key="6">
  31. Option 6
  32. </a-menu-item>
  33. <a-menu-item key="7">
  34. Option 7
  35. </a-menu-item>
  36. <a-menu-item key="8">
  37. Option 8
  38. </a-menu-item>
  39. </a-sub-menu>
  40. <a-sub-menu key="sub2">
  41. <span slot="title"><a-icon type="appstore" /><span>Navigation Two</span></span>
  42. <a-menu-item key="9">
  43. Option 9
  44. </a-menu-item>
  45. <a-menu-item key="10">
  46. Option 10
  47. </a-menu-item>
  48. <a-sub-menu key="sub3" title="Submenu">
  49. <a-menu-item key="11">
  50. Option 11
  51. </a-menu-item>
  52. <a-menu-item key="12">
  53. Option 12
  54. </a-menu-item>
  55. </a-sub-menu>
  56. </a-sub-menu>
  57. </a-menu>
  58. </div>
  59. </template>
  60. <script>
  61. export default {
  62. data() {
  63. return {
  64. collapsed: false,
  65. };
  66. },
  67. methods: {
  68. toggleCollapsed() {
  69. this.collapsed = !this.collapsed;
  70. },
  71. },
  72. };
  73. </script>

Menu导航菜单 - 图4

只展开当前父级菜单

点击菜单,收起其他展开的所有菜单,保持菜单聚焦简洁。

  1. <template>
  2. <div>
  3. <a-menu mode="inline" :open-keys="openKeys" style="width: 256px" @openChange="onOpenChange">
  4. <a-sub-menu key="sub1">
  5. <span slot="title"><a-icon type="mail" /><span>Navigation One</span></span>
  6. <a-menu-item key="1">
  7. Option 1
  8. </a-menu-item>
  9. <a-menu-item key="2">
  10. Option 2
  11. </a-menu-item>
  12. <a-menu-item key="3">
  13. Option 3
  14. </a-menu-item>
  15. <a-menu-item key="4">
  16. Option 4
  17. </a-menu-item>
  18. </a-sub-menu>
  19. <a-sub-menu key="sub2">
  20. <span slot="title"><a-icon type="appstore" /><span>Navigation Two</span></span>
  21. <a-menu-item key="5">
  22. Option 5
  23. </a-menu-item>
  24. <a-menu-item key="6">
  25. Option 6
  26. </a-menu-item>
  27. <a-sub-menu key="sub3" title="Submenu">
  28. <a-menu-item key="7">
  29. Option 7
  30. </a-menu-item>
  31. <a-menu-item key="8">
  32. Option 8
  33. </a-menu-item>
  34. </a-sub-menu>
  35. </a-sub-menu>
  36. <a-sub-menu key="sub4">
  37. <span slot="title"><a-icon type="setting" /><span>Navigation Three</span></span>
  38. <a-menu-item key="9">
  39. Option 9
  40. </a-menu-item>
  41. <a-menu-item key="10">
  42. Option 10
  43. </a-menu-item>
  44. <a-menu-item key="11">
  45. Option 11
  46. </a-menu-item>
  47. <a-menu-item key="12">
  48. Option 12
  49. </a-menu-item>
  50. </a-sub-menu>
  51. </a-menu>
  52. </div>
  53. </template>
  54. <script>
  55. export default {
  56. data() {
  57. return {
  58. rootSubmenuKeys: ['sub1', 'sub2', 'sub4'],
  59. openKeys: ['sub1'],
  60. };
  61. },
  62. methods: {
  63. onOpenChange(openKeys) {
  64. const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1);
  65. if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
  66. this.openKeys = openKeys;
  67. } else {
  68. this.openKeys = latestOpenKey ? [latestOpenKey] : [];
  69. }
  70. },
  71. },
  72. };
  73. </script>

Menu导航菜单 - 图5

垂直菜单

子菜单是弹出的形式。

  1. <template>
  2. <div>
  3. <a-menu style="width: 256px" mode="vertical" @click="handleClick">
  4. <a-menu-item key="1">
  5. <a-icon type="mail" />
  6. Navigation One
  7. </a-menu-item>
  8. <a-menu-item key="2">
  9. <a-icon type="calendar" />
  10. Navigation Two
  11. </a-menu-item>
  12. <a-sub-menu key="sub1">
  13. <span slot="title"><a-icon type="appstore" /><span>Navigation Three</span></span>
  14. <a-menu-item key="3">
  15. Option 3
  16. </a-menu-item>
  17. <a-menu-item key="4">
  18. Option 4
  19. </a-menu-item>
  20. <a-sub-menu key="sub1-2" title="Submenu">
  21. <a-menu-item key="5">
  22. Option 5
  23. </a-menu-item>
  24. <a-menu-item key="6">
  25. Option 6
  26. </a-menu-item>
  27. </a-sub-menu>
  28. </a-sub-menu>
  29. <a-sub-menu key="sub2">
  30. <span slot="title"><a-icon type="setting" /><span>Navigation Four</span></span>
  31. <a-menu-item key="7">
  32. Option 7
  33. </a-menu-item>
  34. <a-menu-item key="8">
  35. Option 8
  36. </a-menu-item>
  37. <a-menu-item key="9">
  38. Option 9
  39. </a-menu-item>
  40. <a-menu-item key="10">
  41. Option 10
  42. </a-menu-item>
  43. </a-sub-menu>
  44. </a-menu>
  45. </div>
  46. </template>
  47. <script>
  48. export default {
  49. methods: {
  50. handleClick(e) {
  51. console.log('click ', e);
  52. },
  53. },
  54. };
  55. </script>

Menu导航菜单 - 图6

主题

内建了两套主题 light|dark,默认 light

  1. <template>
  2. <div>
  3. <a-switch
  4. default-checked
  5. checked-children="dark"
  6. un-checked-children="light"
  7. @change="changeTheme"
  8. />
  9. <br />
  10. <br />
  11. <a-menu
  12. style="width: 256px"
  13. :default-selected-keys="['1']"
  14. :default-open-keys="['sub1']"
  15. mode="inline"
  16. :theme="theme"
  17. :selected-keys="[current]"
  18. @click="handleClick"
  19. >
  20. <a-menu-item key="1">
  21. <a-icon type="mail" />
  22. Navigation One
  23. </a-menu-item>
  24. <a-menu-item key="2">
  25. <a-icon type="calendar" />
  26. Navigation Two
  27. </a-menu-item>
  28. <a-sub-menu key="sub1">
  29. <span slot="title"><a-icon type="appstore" /><span>Navigation Three</span></span>
  30. <a-menu-item key="3">
  31. Option 3
  32. </a-menu-item>
  33. <a-menu-item key="4">
  34. Option 4
  35. </a-menu-item>
  36. <a-sub-menu key="sub1-2" title="Submenu">
  37. <a-menu-item key="5">
  38. Option 5
  39. </a-menu-item>
  40. <a-menu-item key="6">
  41. Option 6
  42. </a-menu-item>
  43. </a-sub-menu>
  44. </a-sub-menu>
  45. <a-sub-menu key="sub2">
  46. <span slot="title"><a-icon type="setting" /><span>Navigation Four</span></span>
  47. <a-menu-item key="7">
  48. Option 7
  49. </a-menu-item>
  50. <a-menu-item key="8">
  51. Option 8
  52. </a-menu-item>
  53. <a-menu-item key="9">
  54. Option 9
  55. </a-menu-item>
  56. <a-menu-item key="10">
  57. Option 10
  58. </a-menu-item>
  59. </a-sub-menu>
  60. </a-menu>
  61. </div>
  62. </template>
  63. <script>
  64. export default {
  65. data() {
  66. return {
  67. current: '1',
  68. theme: 'dark',
  69. };
  70. },
  71. methods: {
  72. handleClick(e) {
  73. console.log('click ', e);
  74. this.current = e.key;
  75. },
  76. changeTheme(checked) {
  77. this.theme = checked ? 'dark' : 'light';
  78. },
  79. },
  80. };
  81. </script>

Menu导航菜单 - 图7

切换菜单类型

展示动态切换模式。

  1. <template>
  2. <div>
  3. <a-switch :default-checked="false" @change="changeMode" /> Change Mode
  4. <span className="ant-divider" style="margin: 0 1em" />
  5. <a-switch :default-checked="false" @change="changeTheme" /> Change Theme
  6. <br />
  7. <br />
  8. <a-menu
  9. style="width: 256px"
  10. :default-selected-keys="['1']"
  11. :default-open-keys="['sub1']"
  12. :mode="mode"
  13. :theme="theme"
  14. >
  15. <a-menu-item key="1">
  16. <a-icon type="mail" />
  17. Navigation One
  18. </a-menu-item>
  19. <a-menu-item key="2">
  20. <a-icon type="calendar" />
  21. Navigation Two
  22. </a-menu-item>
  23. <a-sub-menu key="sub1">
  24. <span slot="title"><a-icon type="appstore" /><span>Navigation Three</span></span>
  25. <a-menu-item key="3">
  26. Option 3
  27. </a-menu-item>
  28. <a-menu-item key="4">
  29. Option 4
  30. </a-menu-item>
  31. <a-sub-menu key="sub1-2" title="Submenu">
  32. <a-menu-item key="5">
  33. Option 5
  34. </a-menu-item>
  35. <a-menu-item key="6">
  36. Option 6
  37. </a-menu-item>
  38. </a-sub-menu>
  39. </a-sub-menu>
  40. <a-sub-menu key="sub2">
  41. <span slot="title"><a-icon type="setting" /><span>Navigation Four</span></span>
  42. <a-menu-item key="7">
  43. Option 7
  44. </a-menu-item>
  45. <a-menu-item key="8">
  46. Option 8
  47. </a-menu-item>
  48. <a-menu-item key="9">
  49. Option 9
  50. </a-menu-item>
  51. <a-menu-item key="10">
  52. Option 10
  53. </a-menu-item>
  54. </a-sub-menu>
  55. </a-menu>
  56. </div>
  57. </template>
  58. <script>
  59. export default {
  60. data() {
  61. return {
  62. mode: 'inline',
  63. theme: 'light',
  64. };
  65. },
  66. methods: {
  67. changeMode(checked) {
  68. this.mode = checked ? 'vertical' : 'inline';
  69. },
  70. changeTheme(checked) {
  71. this.theme = checked ? 'dark' : 'light';
  72. },
  73. },
  74. };
  75. </script>

Menu导航菜单 - 图8

单文件递归菜单

使用单文件方式递归生成菜单。
因组件内部会动态更改a-sub-menu的属性,如果拆分成单文件,无法将属性挂载到a-sub-menu上,你需要自行声明属性并挂载。为了方便,避免属性的声明,我们推荐使用函数式组件。

  1. <template>
  2. <div style="width: 256px">
  3. <a-button type="primary" style="margin-bottom: 16px" @click="toggleCollapsed">
  4. <a-icon :type="collapsed ? 'menu-unfold' : 'menu-fold'" />
  5. </a-button>
  6. <a-menu
  7. :default-selected-keys="['1']"
  8. :default-open-keys="['2']"
  9. mode="inline"
  10. theme="dark"
  11. :inline-collapsed="collapsed"
  12. >
  13. <template v-for="item in list">
  14. <a-menu-item v-if="!item.children" :key="item.key">
  15. <a-icon type="pie-chart" />
  16. <span>{{ item.title }}</span>
  17. </a-menu-item>
  18. <sub-menu v-else :key="item.key" :menu-info="item" />
  19. </template>
  20. </a-menu>
  21. </div>
  22. </template>
  23. <script>
  24. // recommend use functional component
  25. // <template functional>
  26. // <a-sub-menu :key="props.menuInfo.key">
  27. // <span slot="title">
  28. // <a-icon type="mail" /><span>{{ props.menuInfo.title }}</span>
  29. // </span>
  30. // <template v-for="item in props.menuInfo.children">
  31. // <a-menu-item v-if="!item.children" :key="item.key">
  32. // <a-icon type="pie-chart" />
  33. // <span>{{ item.title }}</span>
  34. // </a-menu-item>
  35. // <sub-menu v-else :key="item.key" :menu-info="item" />
  36. // </template>
  37. // </a-sub-menu>
  38. // </template>
  39. // export default {
  40. // props: ['menuInfo'],
  41. // };
  42. import { Menu } from 'ant-design-vue';
  43. const SubMenu = {
  44. template: `
  45. <a-sub-menu :key="menuInfo.key" v-bind="$props" v-on="$listeners">
  46. <span slot="title">
  47. <a-icon type="mail" /><span>{{ menuInfo.title }}</span>
  48. </span>
  49. <template v-for="item in menuInfo.children">
  50. <a-menu-item v-if="!item.children" :key="item.key">
  51. <a-icon type="pie-chart" />
  52. <span>{{ item.title }}</span>
  53. </a-menu-item>
  54. <sub-menu v-else :key="item.key" :menu-info="item" />
  55. </template>
  56. </a-sub-menu>
  57. `,
  58. name: 'SubMenu',
  59. // must add isSubMenu: true
  60. isSubMenu: true,
  61. props: {
  62. ...Menu.SubMenu.props,
  63. // Cannot overlap with properties within Menu.SubMenu.props
  64. menuInfo: {
  65. type: Object,
  66. default: () => ({}),
  67. },
  68. },
  69. };
  70. export default {
  71. components: {
  72. 'sub-menu': SubMenu,
  73. },
  74. data() {
  75. return {
  76. collapsed: false,
  77. list: [
  78. {
  79. key: '1',
  80. title: 'Option 1',
  81. },
  82. {
  83. key: '2',
  84. title: 'Navigation 2',
  85. children: [
  86. {
  87. key: '2.1',
  88. title: 'Navigation 3',
  89. children: [{ key: '2.1.1', title: 'Option 2.1.1' }],
  90. },
  91. ],
  92. },
  93. ],
  94. };
  95. },
  96. methods: {
  97. toggleCollapsed() {
  98. this.collapsed = !this.collapsed;
  99. },
  100. },
  101. };
  102. </script>

API

  1. <template>
  2. <a-menu>
  3. <a-menu-item>菜单项</a-menu-item>
  4. <a-sub-menu title="子菜单">
  5. <a-menu-item>子菜单项</a-menu-item>
  6. </a-sub-menu>
  7. </a-menu>
  8. </template>

Menu

参数说明类型默认值
defaultOpenKeys初始展开的 SubMenu 菜单项 key 数组
defaultSelectedKeys初始选中的菜单项 key 数组string[]
forceSubMenuRender在子菜单展示之前就渲染进 DOMbooleanfalse
inlineCollapsedinline 时菜单是否收起状态boolean-
inlineIndentinline 模式的菜单缩进宽度number24
mode菜单类型,现在支持垂直、水平、和内嵌模式三种string: vertical vertical-right horizontal inlinevertical
multiple是否允许多选booleanfalse
openKeys(.sync)当前展开的 SubMenu 菜单项 key 数组string[]
selectable是否允许选中booleantrue
selectedKeys(v-model)当前选中的菜单项 key 数组string[]
subMenuCloseDelay用户鼠标离开子菜单后关闭延时,单位:秒number0.1
subMenuOpenDelay用户鼠标进入子菜单后开启延时,单位:秒number0
theme主题颜色string: light darklight
overflowedIndicator自定义 Menu 折叠时的图标DOM<span>···</span>

Menu 事件

事件名称说明回调参数
click点击 MenuItem 调用此函数function({ item, key, keyPath })
deselect取消选中时调用,仅在 multiple 生效function({ item, key, selectedKeys })
openChangeSubMenu 展开/关闭的回调function(openKeys: string[])
select被选中时调用function({ item, key, selectedKeys })

Menu.Item

参数说明类型默认值
disabled是否禁用booleanfalse
keyitem 的唯一标志string
title设置收缩时展示的悬浮标题string

Menu.SubMenu

参数说明类型默认值版本
popupClassName子菜单样式string1.5.0
disabled是否禁用booleanfalse
key唯一标志string
title子菜单项值string|slot

Menu.SubMenu 的子元素必须是 MenuItem 或者 SubMenu.

SubMenu 事件

事件名称说明回调参数
titleClick点击子菜单标题({ key, domEvent })

Menu.ItemGroup

参数说明类型默认值
title分组标题string||function|slot

Menu.ItemGroup 的子元素必须是 MenuItem.

Menu.Divider

菜单项分割线,只用在弹出菜单内。