Skip to content

Menu 菜单

为网站提供导航功能的菜单,支持顶部导航、侧边导航和折叠侧栏。

ts
import { createApp } from 'vue'
import { Menu as ElMenu, MenuItem as ElMenuItem, SubMenu as ElSubMenu, MenuItemGroup as ElMenuItemGroup } from '@szhn/dh-design-pc'

const app = createApp()
app.use(ElMenu)
app.use(ElMenuItem)
app.use(ElSubMenu)
app.use(ElMenuItemGroup)

顶栏

mode 设置为 horizontal 可启用水平菜单。通过 sub-menu 可生成二级菜单。

<template>
  <div class="dh-menu-demo-shell">
    <div class="dh-menu-demo-logo">DHdesign</div>
    <el-menu mode="horizontal" :default-active="activeIndex" :ellipsis="false">
      <el-menu-item index="1">
        <el-icon><IconMenu /></el-icon>
        菜单
      </el-menu-item>
      <el-sub-menu index="2">
        <template #title>
          <el-icon><IconMenu /></el-icon>
          菜单
        </template>
        <el-menu-item index="2-1">二级选项</el-menu-item>
        <el-menu-item index="2-2">二级选项</el-menu-item>
        <el-menu-item index="2-3">二级选项</el-menu-item>
      </el-sub-menu>
      <el-menu-item index="3">
        <el-icon><IconMenu /></el-icon>
        菜单
      </el-menu-item>
      <el-menu-item index="4">
        <el-icon><IconMenu /></el-icon>
        菜单
      </el-menu-item>
      <el-menu-item index="5">
        <el-icon><IconMenu /></el-icon>
        菜单
      </el-menu-item>
    </el-menu>
    <div class="dh-menu-demo-actions">
      <el-icon><Search /></el-icon>
      <el-icon><Message /></el-icon>
      <el-icon><Setting /></el-icon>
      <el-icon><User /></el-icon>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { Menu as ElMenu, MenuItem as ElMenuItem, SubMenu as ElSubMenu, Icon as ElIcon } from '@szhn/dh-design-pc'
import { Menu as IconMenu, Message, Search, Setting, User } from '@szhn/dh-design-pc/icons'


const activeIndex = ref('2')
</script>

<style scoped>
.dh-menu-demo-shell {
  position: relative;
  display: flex;
  align-items: center;
  gap: 24px;
  height: 50px;
  padding: 0 24px;
  background: #fff;
}

.dh-menu-demo-shell::after {
  position: absolute;
  right: 24px;
  bottom: 0;
  left: 24px;
  z-index: 1;
  height: 1px;
  background: var(--dh-color-divider);
  content: "";
}

.dh-menu-demo-logo {
  width: 86px;
  color: var(--dh-color-primary);
  font-size: 14px;
  font-weight: 600;
  line-height: 31px;
}

.dh-menu-demo-shell .el-menu {
  flex: 1;
  border-bottom: 0 !important;
}

.dh-menu-demo-actions {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  color: var(--dh-color-text-primary);
  font-size: 18px;
}
</style>

左右布局

水平菜单下可以借助布局容器,将部分菜单项靠右放置。

<template>
  <el-menu mode="horizontal" :default-active="activeIndex" class="demo-menu">
    <el-menu-item index="1">首页</el-menu-item>
    <el-sub-menu index="2">
      <template #title>工作台</template>
      <el-menu-item index="2-1">任务</el-menu-item>
      <el-menu-item index="2-2">项目</el-menu-item>
    </el-sub-menu>
    <div style="flex: 1" />
    <el-menu-item index="3">订阅消息</el-menu-item>
    <el-menu-item index="4">我的</el-menu-item>
  </el-menu>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { Menu as ElMenu, MenuItem as ElMenuItem, SubMenu as ElSubMenu } from '@szhn/dh-design-pc'


const activeIndex = ref('1')
</script>

<style scoped>
.demo-menu {
  display: flex;
}
</style>

侧栏

垂直菜单用于侧边导航,可内嵌子菜单,并支持展开态和收起态。

<template>
  <div class="dh-menu-sidebar-demo">
    <el-menu default-active="1-2" :default-openeds="['1', '3']">
      <div class="dh-menu-sidebar-demo__brand">DHdesign</div>
      <el-sub-menu index="1">
        <template #title>
          <el-icon><IconMenu /></el-icon>
          <span>一级菜单</span>
        </template>
        <el-menu-item index="1-1">二级菜单</el-menu-item>
        <el-menu-item index="1-2">二级菜单</el-menu-item>
        <el-menu-item index="1-3">三级菜单</el-menu-item>
      </el-sub-menu>
      <el-menu-item index="2">
        <el-icon><IconMenu /></el-icon>
        <span>一级菜单</span>
      </el-menu-item>
      <el-sub-menu index="3">
        <template #title>
          <el-icon><IconMenu /></el-icon>
          <span>一级菜单</span>
        </template>
        <el-menu-item index="3-1">二级菜单</el-menu-item>
        <el-menu-item index="3-2">三级菜单</el-menu-item>
      </el-sub-menu>
      <el-menu-item index="4">
        <el-icon><IconMenu /></el-icon>
        <span>一级菜单</span>
      </el-menu-item>
      <el-menu-item index="5">
        <el-icon><IconMenu /></el-icon>
        <span>一级菜单</span>
      </el-menu-item>
    </el-menu>

    <el-menu default-active="2" collapse>
      <div class="dh-menu-sidebar-demo__brand dh-menu-sidebar-demo__brand--collapsed">DH</div>
      <el-menu-item index="1">
        <el-icon><IconMenu /></el-icon>
        <template #title>一级菜单</template>
      </el-menu-item>
      <el-menu-item index="2">
        <el-icon><IconMenu /></el-icon>
        <template #title>一级菜单</template>
      </el-menu-item>
      <el-menu-item index="3">
        <el-icon><IconMenu /></el-icon>
        <template #title>一级菜单</template>
      </el-menu-item>
      <el-menu-item index="4">
        <el-icon><IconMenu /></el-icon>
        <template #title>一级菜单</template>
      </el-menu-item>
      <el-menu-item index="5">
        <el-icon><IconMenu /></el-icon>
        <template #title>一级菜单</template>
      </el-menu-item>
    </el-menu>
  </div>
</template>

<script lang="ts" setup>
import { Menu as ElMenu, MenuItem as ElMenuItem, SubMenu as ElSubMenu, Icon as ElIcon } from '@szhn/dh-design-pc'
import { Menu as IconMenu } from '@szhn/dh-design-pc/icons'

</script>

<style scoped>
.dh-menu-sidebar-demo {
  display: flex;
  gap: 24px;
  align-items: flex-start;
  padding: 24px;
  background: #f7f8fa;
  overflow-x: auto;
}

.dh-menu-sidebar-demo .el-menu {
  min-height: 520px;
}

.dh-menu-sidebar-demo__brand {
  height: 52px;
  padding: 14px 12px 10px;
  color: var(--dh-color-primary);
  font-size: 14px;
  font-weight: 600;
}

.dh-menu-sidebar-demo__brand--collapsed {
  padding-right: 0;
  padding-left: 0;
  text-align: center;
}
</style>

折叠面板

通过 collapse 属性可将垂直菜单折叠。

<template>
  <div class="dh-menu-collapse-demo">
    <el-button style="margin-bottom: 12px" @click="collapse = !collapse">
      {{ collapse ? '展开' : '折叠' }}
    </el-button>
    <div class="dh-menu-collapse-demo__viewport" :class="{ 'is-collapsed': collapse }">
      <el-menu
        class="dh-menu-collapse-demo__menu"
        default-active="1"
        :collapse="collapse"
        :collapse-transition="false"
      >
        <el-menu-item index="1">
          <el-icon><IconLocation /></el-icon>
          <template #title>位置</template>
        </el-menu-item>
        <el-menu-item index="2">
          <el-icon><IconDocument /></el-icon>
          <template #title>文档</template>
        </el-menu-item>
        <el-menu-item index="3">
          <el-icon><IconSetting /></el-icon>
          <template #title>设置</template>
        </el-menu-item>
      </el-menu>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { Menu as ElMenu, MenuItem as ElMenuItem, Button as ElButton, Icon as ElIcon } from '@szhn/dh-design-pc'
import { Location, Document, Setting } from '@szhn/dh-design-pc/icons'

const IconLocation = Location
const IconDocument = Document
const IconSetting = Setting

const collapse = ref(false)
</script>

<style scoped>
.dh-menu-collapse-demo {
  display: inline-flex;
  flex-direction: column;
}

.dh-menu-collapse-demo__viewport {
  width: 224px;
  overflow: hidden;
  transition: width var(--el-transition-duration) var(--el-transition-function-ease-in-out-bezier);
}

.dh-menu-collapse-demo__viewport.is-collapsed {
  width: 80px;
}

</style>

Popper 偏移 (2.4.4)

通过 popper-offset 可以统一调整子菜单弹层与触发项的距离;SubMenu 上单独设置时会覆盖 Menu 上的全局配置。

<template>
  <el-menu
    ellipsis
    mode="horizontal"
    :popper-offset="16"
    style="max-width: 640px"
  >
    <el-menu-item index="1">处理中心</el-menu-item>
    <el-sub-menu index="2">
      <template #title>工作台</template>
      <el-menu-item index="2-1">项目概览</el-menu-item>
      <el-menu-item index="2-2">任务管理</el-menu-item>
      <el-menu-item index="2-3">统计分析</el-menu-item>
      <el-sub-menu index="2-4">
        <template #title>更多操作</template>
        <el-menu-item index="2-4-1">导出报表</el-menu-item>
        <el-menu-item index="2-4-2">权限设置</el-menu-item>
      </el-sub-menu>
    </el-sub-menu>
    <el-sub-menu index="3" :popper-offset="8">
      <template #title>覆盖偏移</template>
      <el-menu-item index="3-1">子项一</el-menu-item>
      <el-menu-item index="3-2">子项二</el-menu-item>
      <el-sub-menu index="3-3" :popper-offset="24">
        <template #title>子级覆盖</template>
        <el-menu-item index="3-3-1">二级一</el-menu-item>
        <el-menu-item index="3-3-2">二级二</el-menu-item>
      </el-sub-menu>
    </el-sub-menu>
    <el-menu-item index="4" disabled>只读</el-menu-item>
    <el-menu-item index="5">订单中心</el-menu-item>
  </el-menu>
</template>

<script lang="ts" setup>
import { Menu as ElMenu, MenuItem as ElMenuItem, SubMenu as ElSubMenu } from '@szhn/dh-design-pc'

</script>

API

属性名说明类型默认值
mode菜单展示模式vertical | horizontalvertical
collapse是否折叠(vertical 时有效)booleanfalse
default-active默认激活菜单的 indexstring''
default-openeds默认展开的 sub-menu 数组string[][]
unique-opened是否只保持一个子菜单展开booleanfalse
router是否启用 vue-router 模式booleanfalse
ellipsis水平模式下是否省略多余项booleantrue
popper-offset 2.4.4全局弹层偏移量number6
menu-trigger水平模式下子菜单触发方式hover | clickhover
事件名说明参数
select菜单激活回调(index, indexPath, item)
opensub-menu 展开回调(index, indexPath)
closesub-menu 收起回调(index, indexPath)
名称说明
open(index)手动展开指定子菜单
close(index)手动收起指定子菜单
handleResize()手动触发宽度重算
updateActiveIndex(index)设置当前激活菜单项
  • MenuItemindex(唯一标识,必填)、disabledroute
  • SubMenuindexdisabledpopper-classshow-timeoutpopper-offset 等。
  • MenuItemGrouptitle 设置分组名。

更多内容参见 Element Plus Menu 文档。