Skip to content

zh-CN

yaml
meta:
  type: 组件
  category: 导航
title: 菜单 Menu
description: 收纳、排列并展示一系列选项的列表。

顶部导航菜单

设置 modehorizontal 时,使用水平菜单。


代码事例
vue
<template>
  <div class="menu-demo">
    <fk-menu mode="horizontal" :default-selected-keys="['1']">
      <fk-menu-item key="0" :style="{ padding: 0, marginRight: '38px' }" disabled>
        <div
          :style="{
            width: '80px',
            height: '30px',
            borderRadius: '2px',
            background: 'var(--color-fill-3)',
            cursor: 'text',
          }"
        />
      </fk-menu-item>
      <fk-menu-item key="1">Home</fk-menu-item>
      <fk-menu-item key="2">Solution</fk-menu-item>
      <fk-menu-item key="3">Cloud Service</fk-menu-item>
      <fk-menu-item key="4">Cooperation</fk-menu-item>
    </fk-menu>
  </div>
</template>
<style scoped>
.menu-demo {
  box-sizing: border-box;
  width: 100%;
  padding: 40px;
  background-color: var(--color-neutral-2);
}
</style>

深色模式导航

通过 theme 指定主题,分为 lightdark 两种。


代码事例
vue
<template>
  <div class="menu-demo">
    <fk-menu mode="horizontal" theme="dark" :default-selected-keys="['1']">
      <fk-menu-item key="0" :style="{ padding: 0, marginRight: '38px' }" disabled>
        <div
          :style="{
            width: '80px',
            height: '30px',
            background: 'var(--color-fill-3)',
            cursor: 'text',
          }"
        />
      </fk-menu-item>
      <fk-menu-item key="1">Home</fk-menu-item>
      <fk-menu-item key="2">Solution</fk-menu-item>
      <fk-menu-item key="3">Cloud Service</fk-menu-item>
      <fk-menu-item key="4">Cooperation</fk-menu-item>
    </fk-menu>
  </div>
</template>
<style scoped>
.menu-demo {
  box-sizing: border-box;
  width: 100%;
  padding: 40px;
  background-color: var(--color-neutral-2);
}
</style>

缩起内嵌菜单

通过 collapsed 来指定菜单收起。


代码事例
vue
<template>
  <div class="menu-demo">
    <fk-button
      :style="{ padding: '0 12px', height: '30px', lineHeight: '30px', marginBottom: '4px' }"
      type="primary"
      @click="toggleCollapse"
    >
      <icon-menu-unfold v-if="collapsed" />
      <icon-menu-fold v-else />
    </fk-button>
    <fk-menu
      :style="{ width: '200px', borderRadius: '4px' }"
      theme="dark"
      :collapsed="collapsed"
      :default-open-keys="['0']"
      :default-selected-keys="['0_2']"
    >
      <fk-sub-menu key="0">
        <template #icon><icon-apps/></template>
        <template #title>Navigation 1</template>
        <fk-menu-item key="0_0">Menu 1</fk-menu-item>
        <fk-menu-item key="0_1">Menu 2</fk-menu-item>
        <fk-menu-item key="0_2">Menu 3</fk-menu-item>
        <fk-menu-item key="0_3">Menu 4</fk-menu-item>
      </fk-sub-menu>
      <fk-sub-menu key="1">
        <template #icon><icon-bug/></template>
        <template #title>Navigation 2</template>
        <fk-menu-item key="1_0">Menu 1</fk-menu-item>
        <fk-menu-item key="1_1">Menu 2</fk-menu-item>
        <fk-menu-item key="1_2">Menu 3</fk-menu-item>
      </fk-sub-menu>
      <fk-sub-menu key="2">
        <template #icon><icon-bulb/></template>
        <template #title>Navigation 3</template>
        <fk-menu-item key="2_0">Menu 1</fk-menu-item>
        <fk-menu-item key="2_1">Menu 2</fk-menu-item>
        <fk-sub-menu key="2_2" title="Navigation 4">
          <fk-menu-item key="2_2_0">Menu 1</fk-menu-item>
          <fk-menu-item key="2_2_1">Menu 2</fk-menu-item>
        </fk-sub-menu>
      </fk-sub-menu>
    </fk-menu>
  </div>
</template>
<script>
import { ref } from 'vue';
import {
  IconApps,
  IconBug,
  IconBulb,
  IconMenuFold,
  IconMenuUnfold,
} from '@erp/common';

export default {
  components: {
    IconMenuFold,
    IconMenuUnfold,
    IconApps,
    IconBug,
    IconBulb,
  },
  setup() {
    const collapsed = ref(false);
    return {
      collapsed,
      toggleCollapse: () => { collapsed.value = !collapsed.value; },
    }
  }
};
</script>
<style scoped>
.menu-demo {
  box-sizing: border-box;
  width: 100%;
  padding: 40px;
  background-color: var(--color-neutral-2);
}
</style>

响应式收缩

设置 breakpoint 可触发响应式收缩。


代码事例
vue
<template>
  <div class="menu-demo">
    <fk-menu
      :style="{ height: '160px' }"
      :collapsed="true"
      id="menu-demo-1"
    >
      <fk-sub-menu key="0" :getTarget="getTarget">
        <template #icon><icon-apps/></template>
        <template #title>订单1</template>
        <fk-menu-item key="0_0">Menu 1</fk-menu-item>
        <fk-menu-item key="0_1">Menu 2</fk-menu-item>
        <fk-menu-item key="0_2">Menu 3</fk-menu-item>
        <fk-menu-item key="0_3">Menu 4</fk-menu-item>
        <fk-menu-item key="0_4">Menu 5</fk-menu-item>
        <fk-menu-item key="0_5">Menu 6</fk-menu-item>
        <fk-menu-item key="0_6">Menu 7</fk-menu-item>
        <fk-menu-item key="0_7">Menu 8</fk-menu-item>
      </fk-sub-menu>
      <fk-sub-menu key="1" :getTarget="getTarget">
        <template #icon><icon-bug/></template>
        <template #title>Navigation 2</template>
        <fk-menu-item key="1_0">Menu 1</fk-menu-item>
        <fk-menu-item key="1_1">Menu 2</fk-menu-item>
        <fk-menu-item key="1_2">Menu 3</fk-menu-item>
      </fk-sub-menu>
      <fk-sub-menu key="2">
        <template #icon><icon-bulb/></template>
        <template #title>Navigation 3</template>
        <fk-menu-item key="2_0">Menu 1</fk-menu-item>
        <fk-menu-item key="2_1">Menu 2</fk-menu-item>
        <fk-sub-menu key="2_2" title="Navigation 4">
          <fk-menu-item key="2_2_0">Menu 1</fk-menu-item>
          <fk-menu-item key="2_2_1">Menu 2</fk-menu-item>
        </fk-sub-menu>
      </fk-sub-menu>
    </fk-menu>
  </div>
</template>
<script>
import { ref } from 'vue';
import { Message } from '@erp/common';
import {
  IconApps,
  IconBug,
  IconBulb,
  IconMenuFold,
  IconMenuUnfold,
} from '@erp/common';

export default {
  components: {
    IconMenuFold,
    IconMenuUnfold,
    IconApps,
    IconBug,
    IconBulb,
  },
  setup() {
    return {
      onCollapse(val, type) {
        const content = type === 'responsive' ? '触发响应式收缩' : '点击触发收缩';
        Message.info({
          content,
          duration: 2000,
        });
      },
      getTarget() {
        return document.querySelector('#menu-demo-1');
      }
    };
  }
};
</script>
<style scoped>
.menu-demo {
  box-sizing: border-box;
  width: 100%;
  height: 600px;
  padding: 40px;
  background-color: var(--color-neutral-2);
}
</style>

内嵌菜单

菜单内可以嵌入多个子项,通过 openKeys 可以设置默认打开的子项。


代码事例
vue
<template>
  <div class="menu-demo">
    <fk-menu
      :style="{ width: '200px', height: '100%' }"
      :default-open-keys="['0']"
      :default-selected-keys="['0_1']"
      show-collapse-button
    >
    <fk-menu-item key="0_0_0" datfk-obj="1">Menu 1</fk-menu-item>
      <fk-sub-menu autoFitPopupWidth key="0" fitPopupWithElement="#menu">
        <template #icon><icon-apps/></template>
        <template #title>Navigation 1</template>
        <fk-menu-item key="0_0">Menu 1</fk-menu-item>
        <fk-menu-item key="0_1">Menu 2</fk-menu-item>
        <fk-menu-item key="0_2" disabled>Menu 3</fk-menu-item>
      </fk-sub-menu>
      <fk-sub-menu autoFitPopupWidth key="1" fitPopupWithElement="#menu">
        <template #icon><icon-bug/></template>
        <template #title>Navigation 2</template>
        <fk-menu-item key="1_0">Menu 1</fk-menu-item>
        <fk-menu-item key="1_1">Menu 2</fk-menu-item>
        <fk-menu-item key="1_2">Menu 3</fk-menu-item>
      </fk-sub-menu>
      <fk-sub-menu key="2" fitPopupWithElement="#menu">
        <template #icon><icon-bulb/></template>
        <template #title>Navigation 3</template>
        <fk-menu-item-group>
          <template #title>
            常用
            <fk-button type="text">管理</fk-button>
          </template>
          <fk-menu-item class="menu-item-wrap" key="2_0">
            Menu 1
            <template #suffix><IconPushpin /></template>
          </fk-menu-item>
          <fk-menu-item key="2_1">Menu 2</fk-menu-item>
        </fk-menu-item-group>
        <fk-menu-item-group title="Menu Group 2">
          <fk-menu-item key="2_2">Menu 3 <IconPushpin /></fk-menu-item>
          <fk-menu-item key="2_3">Menu 4</fk-menu-item>
        </fk-menu-item-group>
      </fk-sub-menu>
    </fk-menu>
  </div>
</template>
<script>
import {
  IconApps,
  IconBug,
  IconBulb,
  IconMenuFold,
  IconMenuUnfold,
  IconPushpin,
} from '@erp/common';

export default {
  components: {
    IconPushpin,
    IconMenuFold,
    IconMenuUnfold,
    IconApps,
    IconBug,
    IconBulb,
  },
};
</script>
<style scoped>
.menu-demo {
  box-sizing: border-box;
  width: 100%;
  height: 600px;
  padding: 40px;
  background-color: var(--color-neutral-2);
}
.menu-item {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
}
:deep(.fk-menu-popup-wrapper) {
  height: 100%;
}
</style>

不同大小菜单

通过 style 自由指定菜单的宽度和菜单项的高度。


代码事例
vue
<template>
  <div class="menu-demo">
    <fk-slider
      v-model="width"
      :style="{ width: '320px', marginBottom: '24px' }"
      :step="10"
      :min="160"
      :max="400"
    />
    <fk-menu
      show-collapse-button
      :default-open-keys="['0']"
      :default-selected-keys="['0_1']"
      :style="{ width: `${width}px`, height: 'calc(100% - 28px)' }"
    >
      <fk-sub-menu key="0">
        <template #icon><IconApps/></template>
        <template #title>Navigation 1</template>
        <fk-menu-item key="0_0">Menu 1</fk-menu-item>
        <fk-menu-item key="0_1">Menu 2</fk-menu-item>
        <fk-menu-item key="0_2" disabled>
          Menu 3
        </fk-menu-item>
      </fk-sub-menu>
      <fk-sub-menu key="1">
        <template #icon><IconBug/></template>
        <template #title>Navigation 2</template>
        <fk-menu-item key="1_0">Menu 1</fk-menu-item>
        <fk-menu-item key="1_1">Menu 2</fk-menu-item>
        <fk-menu-item key="1_2">Menu 3</fk-menu-item>
      </fk-sub-menu>
      <fk-sub-menu key="2">
        <template #icon><IconBulb/></template>
        <template #title>Navigation 3</template>
        <fk-menu-item key="2_0">Menu 1</fk-menu-item>
        <fk-menu-item key="2_1">Menu 2</fk-menu-item>
        <fk-menu-item key="2_2">Menu 3</fk-menu-item>
      </fk-sub-menu>
    </fk-menu>
  </div>
</template>
<script>
import {
  IconApps,
  IconBug,
  IconBulb,
  IconMenuFold,
  IconMenuUnfold,
} from '@erp/common';

export default {
  components: {
    IconMenuFold,
    IconMenuUnfold,
    IconApps,
    IconBug,
    IconBulb,
  },
  data() {
    return {
      width: 240
    }
  }
};
</script>
<style scoped>
.menu-demo {
  box-sizing: border-box;
  width: 100%;
  height: 600px;
  padding: 40px;
  background-color: var(--color-neutral-2);
}
</style>

悬浮菜单

指定 modepop 可以使用悬浮菜单。


代码事例
vue
<template>
  <div class="menu-demo">
    <fk-menu mode="pop" show-collapse-button>
      <fk-menu-item key="1">
        <template #icon><icon-apps/></template>
        Navigation 1
      </fk-menu-item>
      <fk-sub-menu key="2">
        <template #icon><icon-bug/></template>
        <template #title>Navigation 2</template>
        <fk-menu-item key="2_0">Beijing</fk-menu-item>
        <fk-menu-item key="2_1">Shanghai</fk-menu-item>
        <fk-menu-item key="2_2">Guangzhou</fk-menu-item>
      </fk-sub-menu>
      <fk-sub-menu key="3">
        <template #icon><icon-bulb/></template>
        <template #title>Navigation 3</template>
        <fk-menu-item key="3_0">Wuhan</fk-menu-item>
        <fk-menu-item key="3_1">Chengdu</fk-menu-item>
      </fk-sub-menu>
      <fk-menu-item key="4">
        <template #icon><icon-safe/></template>
        Navigation 4
      </fk-menu-item>
      <fk-menu-item key="5">
        <template #icon><icon-fire/></template>
        Navigation 5
      </fk-menu-item>
    </fk-menu>
  </div>
</template>
<script>
import {
  IconApps,
  IconBug,
  IconBulb,
} from '@erp/common';

export default {
  components: {
    IconApps,
    IconBug,
    IconBulb,
  },
};
</script>
<style scoped>
.menu-demo {
  width: 100%;
  height: 600px;
  padding: 40px;
  box-sizing: border-box;
  background-color: var(--color-neutral-2);
}

.menu-demo .fk-menu {
  width: 200px;
  height: 100%;
  box-shadow: 0 0 1px rgba(0, 0, 0, 0.3);
}

.menu-demo .fk-menu :deep(.fk-menu-collapse-button) {
  width: 32px;
  height: 32px;
  border-radius: 50%;
}

.menu-demo .fk-menu:not(.fk-menu-collapsed) :deep(.fk-menu-collapse-button) {
  right: 0;
  bottom: 8px;
  transform: translateX(50%);
}

.menu-demo .fk-menu:not(.fk-menu-collapsed)::before {
  content: '';
  position: absolute;
  right: 0;
  bottom: 0;
  width: 48px;
  height: 48px;
  background-color: inherit;
  border-radius: 50%;
  box-shadow: -4px 0 2px var(--color-bg-2), 0 0 1px rgba(0, 0, 0, 0.3);
  transform: translateX(50%);
}

.menu-demo .fk-menu.fk-menu-collapsed {
  width: 48px;
  height: auto;
  padding-top: 24px;
  padding-bottom: 138px;
  border-radius: 22px;
}

.menu-demo .fk-menu.fk-menu-collapsed :deep(.fk-menu-collapse-button) {
  right: 8px;
  bottom: 8px;
}
</style>

悬浮按钮菜单

指定 modepopButton 使用按钮组样式的悬浮菜单。


代码事例
vue
<template>
  <div class="menu-demo">
    <fk-trigger
      v-model:popupVisible="popupVisible1"
      :trigger="['click', 'hover']"
      click-to-close
      position="top"
    >
      <div :class="`button-trigger ${popupVisible1 ? 'button-trigger-active' : ''}`">
        <IconClose v-if="popupVisible1" />
        <IconMessage v-else />
      </div>
      <template #content>
        <fk-menu
          :style="{ marginBottom: '-4px' }"
          mode="popButton"
          :tooltip-props="{ position: 'left' }"
          show-collapse-button
        >
          <fk-menu-item key="1">
            <template #icon><IconBug/></template>
            Bugs
          </fk-menu-item>
          <fk-menu-item key="2">
            <template #icon><IconBulb/></template>
            Ideas
          </fk-menu-item>
        </fk-menu>
      </template>
    </fk-trigger>

    <fk-trigger
      v-model:popupVisible="popupVisible2"
      :trigger="['click', 'hover']"
      click-to-close
      position="top"
    >
      <div :class="`button-trigger ${popupVisible2 ? 'button-trigger-active' : ''}`">
        <IconClose v-if="popupVisible2" />
        <IconMessage v-else />
      </div>
      <template #content>
        <fk-menu
          :style="{ marginBottom: '-4px' }"
          mode="popButton"
          :tooltip-props="{ position: 'left' }"
          show-collapse-button
        >
          <fk-menu-item key="1">
            <template #icon><IconBug/></template>
            Bugs
          </fk-menu-item>
          <fk-menu-item key="2">
            <template #icon><IconBulb/></template>
            Ideas
          </fk-menu-item>
        </fk-menu>
      </template>
    </fk-trigger>
  </div>
</template>
<script>
import {
  IconBug,
  IconBulb,
  IconClose,
  IconMessage,
} from '@erp/common';

export default {
  components: {
    IconBug,
    IconBulb,
    IconClose,
    IconMessage,
  },
  data() {
    return {
      popupVisible1: false,
      popupVisible2: false,
    };
  }
};
</script>
<style scoped>
.menu-demo {
  box-sizing: border-box;
  width: 660px;
  height: 300px;
  padding: 40px;
  background-color: var(--color-fill-2);
  position: relative;
}
.button-trigger {
  position: absolute;
  bottom: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  color: var(--color-white);
  font-size: 14px;
  border-radius: 50%;
  cursor: pointer;
  transition: all 0.1s;
}
/* button left */
.button-trigger:nth-child(1) {
  left: 150px;
  background-color: var(--color-neutral-5);
}
.button-trigger:nth-child(1).button-trigger-active {
  background-color: var(--color-neutral-4);
}
/* button right */
.button-trigger:nth-child(2) {
  left: 372px;
  background-color: rgb(var(--fkblue-6));
}
.button-trigger:nth-child(3).button-trigger-active {
  background-color: var(--color-primary-light-4);
}
</style>

API

参数名描述类型默认值
theme菜单的主题'light' | 'dark''light'
mode菜单的模式'vertical' | 'horizontal' | 'pop' | 'popButton''vertical'
level-indent层级之间的缩进量number-
auto-open默认展开所有多级菜单booleanfalse
collapsed (v-model)是否折叠菜单boolean-
default-collapsed默认是否折叠菜单booleanfalse
collapsed-width折叠菜单宽度number-
accordion开启手风琴效果booleanfalse
auto-scroll-into-view是否自动滚动选中项目到可见区域booleanfalse
show-collapse-button是否内置折叠按钮booleanfalse
selected-keys (v-model)选中的菜单项 key 数组string[]-
default-selected-keys默认选中的菜单项 key 数组string[][]
open-keys (v-model)展开的子菜单 key 数组string[]-
default-open-keys默认展开的子菜单 key 数组string[][]
scroll-config滚动到可见区域的配置项,接收所有scroll-into-view-if-needed的参数{ [key: string]: any }-
trigger-props弹出模式下可接受所有 TriggerPropsTriggerProps-
tooltip-props弹出模式下可接受所有 ToolTipPropsobject-
auto-open-selected默认展开选中的菜单booleanfalse
breakpoint响应式的断点, 详见响应式栅格'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'-
popup-max-height弹出框的最大高度boolean | numbertrue
事件名描述参数
collapse折叠状态改变时触发collapsed: boolean
type: 'clickTrigger'|'responsive'
menu-item-click点击菜单项时触发key: string
sub-menu-click点击子菜单时触发key: string
openKeys: string[]
插槽名描述参数
collapse-icon折叠图标collapsed: boolean
expand-icon-right向右展开的图标-
expand-icon-down向下展开的图标-
参数名描述类型默认值
title子菜单的标题string-
selectable弹出模式下,是否将多级菜单头也作为一个菜单项,支持点击选中等状态booleanfalse
popup是否强制使用弹出模式,level 表示当前子菜单的层级boolean | ((level: number) => boolean)false
popup-max-height弹出框的最大高度boolean | numberundefined
插槽名描述参数
title标题-
expand-icon-right向右展开的图标-
expand-icon-down向下展开的图标-
icon菜单的图标-
参数名描述类型默认值
title菜单组的标题string-
插槽名描述参数
title标题-
suffix后缀-
参数名描述类型默认值
disabled是否禁用booleanfalse
插槽名描述参数
icon菜单的图标-
suffix菜单的后缀-

FAQ

<Menu> 组件中使用 <MenuItem><SubMenu> 组件时,请传入唯一的 key 属性。 组件内部在进行计算时会依赖此值,如果没有赋值会导致部分场景下异常


基于 MIT 许可发布