- 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-switch
defaultChecked
@change="changeTheme"
checkedChildren="dark"
unCheckedChildren="light"
/>
<br />
<br />
<a-menu
style="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-menu
style="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
菜单项分割线,只用在弹出菜单内。