Skip to content
API 风格:

Menu 导航菜单 ​

页面导航组件。支持水平 / 垂直布局、嵌套子菜单、折叠态、手风琴,键盘对齐 APG menu pattern。

垂直布局(内联子菜单) ​

垂直内联模式支持键盘遍历:展开子菜单后 ↑/↓ 可跨「叶子项 ↔ 子菜单标题 ↔ 面板内项」边界移动(Home/End 跳首末),禁用项与收起面板内的项自动跳过。

垂直布局
vue
<script setup>
import { ref } from 'vue'
const active = ref('home')
const active2 = ref('settings2-basic')
</script>

<template>
  <!-- 垂直布局 -->
  <LhMenu v-model="active">
    <LhMenuItem index="home">首页</LhMenuItem>
    <LhSubMenu index="settings" title="设置">
      <LhMenuItem index="settings-basic">基本设置</LhMenuItem>
      <LhMenuItem index="settings-security">安全设置</LhMenuItem>
    </LhSubMenu>
    <LhMenuItem index="docs" disabled>禁用项</LhMenuItem>
  </LhMenu>
</template>
vue
<script>
export default {
  data() {
    return {
      active: 'home',
      active2: 'settings2-basic',
    }
  },
}
</script>

<template>
  <!-- 垂直布局 -->
  <LhMenu v-model="active">
    <LhMenuItem index="home">首页</LhMenuItem>
    <LhSubMenu index="settings" title="设置">
      <LhMenuItem index="settings-basic">基本设置</LhMenuItem>
      <LhMenuItem index="settings-security">安全设置</LhMenuItem>
    </LhSubMenu>
    <LhMenuItem index="docs" disabled>禁用项</LhMenuItem>
  </LhMenu>
</template>

展开控制 ​

default-openeds 初始展开的子菜单;openeds(配合 v-model:openeds)受控展开集合;unique-opened 同时只展开一个子菜单。LhSubMenu 也支持 disabled 整体禁用。

展开控制
  • vue
    <script setup>
    import { ref } from 'vue'
    const active2 = ref('settings2-basic')
    </script>
    
    <template>
      <!-- 展开控制 -->
      <LhMenu
        v-model="active2"
        :default-openeds="['settings2']"
        unique-opened
        style="max-width: 240px"
      >
        <LhSubMenu index="settings2" title="设置(默认展开)">
          <LhMenuItem index="settings2-basic">基本设置</LhMenuItem>
          <LhMenuItem index="settings2-security">安全设置</LhMenuItem>
        </LhSubMenu>
        <LhSubMenu index="manage" title="管理(禁用)" disabled>
          <LhMenuItem index="manage-users">用户管理</LhMenuItem>
        </LhSubMenu>
        <LhMenuItem index="about2">关于</LhMenuItem>
      </LhMenu>
    </template>
    vue
    <script>
    export default {
      data() {
        return { active2: 'settings2-basic' }
      },
    }
    </script>
    
    <template>
      <!-- 展开控制 -->
      <LhMenu
        v-model="active2"
        :default-openeds="['settings2']"
        unique-opened
        style="max-width: 240px"
      >
        <LhSubMenu index="settings2" title="设置(默认展开)">
          <LhMenuItem index="settings2-basic">基本设置</LhMenuItem>
          <LhMenuItem index="settings2-security">安全设置</LhMenuItem>
        </LhSubMenu>
        <LhSubMenu index="manage" title="管理(禁用)" disabled>
          <LhMenuItem index="manage-users">用户管理</LhMenuItem>
        </LhSubMenu>
        <LhMenuItem index="about2">关于</LhMenuItem>
      </LhMenu>
    </template>
    受控展开集合
    vue
    <script setup lang="ts">
    import { ref } from 'vue'
    
    const active2 = ref('settings2-basic')
    </script>
    
    <template>
      <!-- 受控展开集合 -->
      <LhMenu v-model="active2" :openeds="['settings2']">
        <LhSubMenu index="settings2" title="设置">
          <LhMenuItem index="settings2-basic">基本设置</LhMenuItem>
        </LhSubMenu>
      </LhMenu>
    </template>
    vue
    <script>
    export default {
      data() {
        return { active2: 'settings2-basic' }
      },
    }
    </script>
    
    <template>
      <!-- 受控展开集合 -->
      <LhMenu v-model="active2" :openeds="['settings2']">
        <LhSubMenu index="settings2" title="设置">
          <LhMenuItem index="settings2-basic">基本设置</LhMenuItem>
        </LhSubMenu>
      </LhMenu>
    </template>

    水平布局(飞出子菜单) ​

    水平布局
    vue
    <script setup lang="ts">
    import { ref } from 'vue'
    
    const active = ref('home')
    </script>
    
    <template>
      <!-- 水平布局 -->
      <LhMenu v-model="active" mode="horizontal">
        <LhMenuItem index="home">首页</LhMenuItem>
        <LhSubMenu index="settings" title="设置">
          <LhMenuItem index="settings-basic">基本设置</LhMenuItem>
        </LhSubMenu>
      </LhMenu>
    </template>
    vue
    <script>
    export default {
      data() {
        return { active: 'home' }
      },
    }
    </script>
    
    <template>
      <!-- 水平布局 -->
      <LhMenu v-model="active" mode="horizontal">
        <LhMenuItem index="home">首页</LhMenuItem>
        <LhSubMenu index="settings" title="设置">
          <LhMenuItem index="settings-basic">基本设置</LhMenuItem>
        </LhSubMenu>
      </LhMenu>
    </template>

    折叠态与分组 ​

    折叠 + 分组
    vue
    <script setup lang="ts">
    import { ref } from 'vue'
    
    const active = ref('home')
    </script>
    
    <template>
      <!-- 折叠 + 分组 -->
      <LhMenu v-model="active" collapse>
        <LhMenuItemGroup title="内容">
          <LhMenuItem index="home">首页</LhMenuItem>
        </LhMenuItemGroup>
      </LhMenu>
    </template>
    vue
    <script>
    export default {
      data() {
        return { active: 'home' }
      },
    }
    </script>
    
    <template>
      <!-- 折叠 + 分组 -->
      <LhMenu v-model="active" collapse>
        <LhMenuItemGroup title="内容">
          <LhMenuItem index="home">首页</LhMenuItem>
        </LhMenuItemGroup>
      </LhMenu>
    </template>

    API ​

    LhMenu Props ​

    属性名说明类型默认值
    modelValue当前激活项(受控 v-model;未传时内部维护)string—
    mode布局模式"horizontal" | "vertical"'vertical'
    collapse垂直模式折叠为图标条(子菜单改为飞出面板)booleanfalse
    defaultOpeneds默认展开的子菜单键(非受控)string[]() => []
    openeds受控展开的子菜单键string[]—
    uniqueOpened手风琴:同时只展开一个子菜单booleanfalse
    sxsx 快速布局属性LhSxProps—

    Events ​

    事件名说明回调参数
    update:modelValue激活项变化时触发(v-model)(value: string)
    update:openeds展开的子菜单集合变化时触发(v-model:openeds)(value: string[])
    select菜单项被选中时触发(index: string, indexPath: string[])
    open子菜单展开时触发(index: string, indexPath: string[])
    close子菜单收起时触发(index: string, indexPath: string[])

    LhMenuItem Props ​

    属性名说明类型默认值
    index唯一标识(必填)string—
    disabled禁用booleanfalse
    sxsx 快速布局属性LhSxProps—

    事件:click(index);插槽:default。

    LhSubMenu Props ​

    属性名说明类型默认值
    index唯一标识(必填)string—
    title标题(也可用 title 插槽)string—
    disabled禁用booleanfalse
    sxsx 快速布局属性LhSxProps—

    事件:select(index, indexPath)(冒泡);插槽:title、default(可再嵌套 LhSubMenu)。

    LhMenuItemGroup Props ​

    属性名说明类型默认值
    title分组标题(也可用 title 插槽)string—
    sxsx 快速布局属性LhSxProps—

    插槽:title、default。

    无障碍 ​

    类型定义 ​

    本组件对外导出的 TypeScript 类型结构如下(自动提取自 packages/components/menu/src/types.ts 与 @lh-ui/share/core/* 源码,点击各条目展开查看完整定义;属性说明见上方 Props 表):

    LhMenuProps
    ts
    /** 菜单 props */
    export interface LhMenuProps {
      /** 当前激活项(受控 v-model;未传时组件内部维护) */
      modelValue?: string
      /** 布局模式 */
      mode?: LhMenuMode
      /** 垂直模式折叠为图标条(子菜单改为飞出面板) */
      collapse?: boolean
      /** 默认展开的子菜单键(非受控) */
      defaultOpeneds?: string[]
      /** 受控展开的子菜单键 */
      openeds?: string[]
      /** 手风琴:同时只展开一个子菜单 */
      uniqueOpened?: boolean
      /** sx 快速布局属性 */
      sx?: LhSxProps
    }
    LhMenuItemProps
    ts
    /** 叶子项 props */
    export interface LhMenuItemProps {
      /** 唯一标识(必填) */
      index: string
      disabled?: boolean
      /** sx 快速布局属性 */
      sx?: LhSxProps
    }
    LhSubMenuProps
    ts
    /** 子菜单 props(可递归嵌套) */
    export interface LhSubMenuProps {
      /** 唯一标识(必填) */
      index: string
      /** 标题(也可用 title 插槽) */
      title?: string
      disabled?: boolean
      /** sx 快速布局属性 */
      sx?: LhSxProps
    }
    LhMenuItemGroupProps
    ts
    /** 分组 props */
    export interface LhMenuItemGroupProps {
      /** 分组标题(也可用 title 插槽) */
      title?: string
      /** sx 快速布局属性 */
      sx?: LhSxProps
    }
    LhMenuMode (来自 @lh-ui/share/core/menu)
    ts
    /** 菜单布局模式 */
    export type LhMenuMode = 'horizontal' | 'vertical'