Menu 菜单

Menu 组件通常用于导航.

何时使用

在需要收纳,排列,展示一系列选项时.

基本用法

如果屏幕尺寸过小,则会出现省略号
<template>
  <d-menu mode="horizontal" :default-select-keys="['home']" style="margin-bottom: 120px" :width="width + 'px'">
    <d-menu-item key="home">
      <template #icon>
        <i class="icon-homepage"></i>
      </template>
      首页
    </d-menu-item>
    <d-sub-menu title="课程" key="course">
      <d-menu-item key="c"> C </d-menu-item>
      <d-sub-menu title="Python" key="python" disabled>
        <d-menu-item key="basic"> 基础 </d-menu-item>
        <d-menu-item key="advanced"> 进阶 </d-menu-item>
      </d-sub-menu>
    </d-sub-menu>
    <d-menu-item key="person">个人</d-menu-item>
    <d-menu-item key="custom" href="https://www.baidu.com" disabled> Link To Baidu </d-menu-item>
  </d-menu>
  <d-slider :min="0" :max="480" v-model="width"></d-slider>
</template>

<script setup lang="ts">
import { ref } from 'vue';
let width = ref(480);
</script>

自定义图标

有时我们需要为子菜单或菜单项定义一些图标,此时我们可以使用icon插槽来为菜单定义 icon。同时我们也可以使用 css 来对插槽进行定制化的修改.

  • 主页
  • 课程
<template>
  <d-menu mode="horizontal">
    <d-menu-item key="home">
      <template #icon>
        <i class="icon-homepage"></i>
      </template>
      主页
    </d-menu-item>
    <d-menu-item key="course"> 课程 </d-menu-item>
  </d-menu>
</template>

垂直菜单

垂直菜单一般在后台中较为广泛使用,子菜单可以嵌入菜单中

  • Home
    • System
<template>
  <d-menu mode="vertical" :default-select-keys="['item1']" width="256px">
    <d-menu-item key="item1">
      <template #icon>
        <i class="icon-homepage"></i>
      </template>
      <span>Home</span>
    </d-menu-item>
    <d-sub-menu title="System" key="system">
      <template #icon>
        <i class="icon-system"></i>
      </template>
      <d-menu-item key="system-item">
        <span>System item</span>
      </d-menu-item>
      <d-sub-menu title="Setting" key="setting">
        <template #icon>
          <i class="icon-setting"></i>
        </template>
        <d-menu-item key="setting-item">
          <span>Setting item</span>
        </d-menu-item>
      </d-sub-menu>
    </d-sub-menu>
  </d-menu>
</template>

默认展开

通过设置open-keys可以修改展开的子菜单项目.

      sub1
    • Sub1 > item1
    • Sub1 > item2
      sub2
      sub3
    • Sub3 > item1
    • Sub3 > item2
<template>
  <d-menu width="256px" mode="vertical" :open-keys="['sub1', 'sub3']">
    <d-sub-menu key="sub1" title="sub1">
      <d-menu-item key="Sub1-item1"> Sub1 > item1 </d-menu-item>
      <d-menu-item key="Sub1-item2"> Sub1 > item2 </d-menu-item>
    </d-sub-menu>
    <d-sub-menu key="sub2" title="sub2">
      <d-menu-item key="Sub2-item1"> Sub2 > item1 </d-menu-item>
      <d-menu-item key="Sub2-item2"> Sub2 > item2 </d-menu-item>
    </d-sub-menu>
    <d-sub-menu key="sub3" title="sub3">
      <d-menu-item key="Sub3-item1"> Sub3 > item1 </d-menu-item>
      <d-menu-item key="Sub3-item2"> Sub3 > item2 </d-menu-item>
    </d-sub-menu>
  </d-menu>
</template>

仅展开一项根子菜单

      submenu-1
    • submenu-item-1
      • submenu-4
        submenu-5
      submenu-2
      submenu-3
通过子菜单状态改变事件修改open-keys数组达到效果
  <template>
    <d-menu @submenu-change="submenuChange" :default-select-keys="['item1']" :open-keys="openKeys" width="256px"
    >
      <d-sub-menu title="submenu-1" key="submenu-1">
        <template #icon>
          <i class="icon-infomation"></i>
        </template>
        <d-menu-item key="subemenu-item-1">
          <span>submenu-item-1</span>
        </d-menu-item>
        <d-sub-menu title="submenu-4" key="submenu-4">
          <template #icon>
            <i class="icon-infomation"></i>
          </template>
          <d-menu-item key="subemenu-item-1">
            <span>submenu-item-1</span>
          </d-menu-item>
        </d-sub-menu>
        <d-sub-menu title="submenu-5" key="submenu-5">
          <template #icon>
            <i class="icon-infomation"></i>
          </template>
          <d-menu-item key="subemenu-item-1">
            <span>submenu-item-1</span>
          </d-menu-item>
        </d-sub-menu>
      </d-sub-menu>
      <d-sub-menu title="submenu-2" key="submenu-2">
        <template #icon>
          <i class="icon-setting"></i>
        </template>
        <d-menu-item key="submenu-item-2">
          <span>submenu-item-2</span>
        </d-menu-item>
      </d-sub-menu>
      <d-sub-menu title="submenu-3" key="submenu-3">
        <template #icon>
          <i class="icon-setting"></i>
        </template>
        <d-menu-item key="submenu-item-2">
          <span>submenu-item-2</span>
        </d-menu-item>
      </d-sub-menu>
    </d-menu>
  </template>

  <script>
  import { defineComponent, ref } from 'vue';

  export default defineComponent({
    setup() {
      const openKeys = ref(['submenu-1']);
      const rootSubMenuKeys = ref(['submenu-1','submenu-2','submenu-3']);
      const submenuChange = (e) => {
        console.log(e);
        const {key} = e;
        if (rootSubMenuKeys.value.includes(key)){
          while (openKeys.value.length){
            openKeys.value.shift();
          }
          openKeys.value.push(key);
        }
      };
      return {
        openKeys,
        submenuChange,
      };
    },
  });
  </script>

收缩菜单

  • Home
    • System
<d-button @click="changeCollapsed">
  Collapsed
</d-button>
<template>
  <d-menu :collapsed-indent="48" mode="vertical" width="256px" :default-select-keys="['item1']" :collapsed="collapsed">
    <d-menu-item key="item1" :disabled="isDisabled">
      <template #icon>
        <i class="icon-homepage"></i>
      </template>
      <span>Home</span>
    </d-menu-item>
    <d-sub-menu title="System" key="system">
      <template #icon>
        <i class="icon-system"></i>
      </template>
      <d-menu-item key="system-item">
        <span>System item</span>
      </d-menu-item>
      <d-sub-menu title="Setting" key="setting">
        <template #icon>
          <i class="icon-setting"></i>
        </template>
        <d-menu-item key="setting-item">
          <span>Setting item</span>
        </d-menu-item>
      </d-sub-menu>
    </d-sub-menu>
  </d-menu>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
let collapsed = ref(false);
const isDisabled = ref(true);
const changeCollapsed = () => {
  collapsed.value = !collapsed.value;
};
</script>

取消多选

取消多选功能仅能使用在允许多选的菜单中,菜单项将会在取消多选时触发deselect事件。

  • Item1
  • Item2
    • Setting
<template>
  <d-menu @select="select" @deselect="deselect" @submenu-change="submenuChange" :default-select-keys="['item1']" multiple width="256px">
    <d-menu-item key="item1"> Item1 </d-menu-item>
    <d-menu-item key="item2"> Item2 </d-menu-item>
    <d-sub-menu title="Setting" key="icon-setting">
      <template #icon>
        <i class="icon-setting"></i>
      </template>
      <d-menu-item key="setting-item">
        <span>Setting item</span>
      </d-menu-item>
    </d-sub-menu>
  </d-menu>
</template>

<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const select = (e) => {
      console.log(e);
    };
    const deselect = (e) => {
      console.log(e);
    };
    const submenuChange = (e) => {
      console.log(e);
    };
    return {
      select,
      deselect,
      submenuChange,
    };
  },
});
</script>

响应式参数

例如,width, open-keys, default-select-keys等参数均为响应式

  • Home
    • System

<template>
  <d-button @click="changeDisabled">changeDisabled</d-button>
  <d-button @click="addSelect">change select</d-button>
  <d-menu mode="vertical" :width="width + 'px'" :default-select-keys="selectKeys" :collapsed="collapsed">
    <d-menu-item key="item1" :disabled="isDisabled">
      <template #icon>
        <i class="icon-homepage"></i>
      </template>
      <span>Home</span>
    </d-menu-item>
    <d-sub-menu title="System" key="icon-system">
      <template #icon>
        <i class="icon-system"></i>
      </template>
      <d-menu-item key="system-item">
        <span>System item</span>
      </d-menu-item>
      <d-sub-menu title="Setting" key="icon-setting">
        <template #icon>
          <i class="icon-setting"></i>
        </template>
        <d-menu-item key="setting-item">
          <span>Setting item</span>
        </d-menu-item>
      </d-sub-menu>
    </d-sub-menu>
  </d-menu>
  <br />
  <d-slider :min="0" :max="480" v-model="width"></d-slider>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
let collapsed = ref(false);
let isDisabled = ref(false);
let selectKeys = ref([]);
let width = ref(256);
const changeDisabled = () => {
  isDisabled.value = !isDisabled.value;
  console.log(isDisabled.value);
};
const addSelect = () => {
  if (selectKeys.value.includes('system-item')){
    selectKeys.value.pop();
  } else {
    selectKeys.value.push('system-item');
  }
  console.log(selectKeys.value);
}
</script>
参数类型默认说明跳转 Demo
widthString''用于控制菜单宽度响应式参数
collapsedBooleanfalse用于决定菜单是否收起收缩菜单
collapsed-indentNumber24收起时图标距离左右边框的距离收缩菜单
multipleBooleanfalse是否可以多选取消多选
modemenuMode'vertical'菜单类型基本用法
open-keysArray[]默认展开的子菜单 key 值默认展开
default-select-keysArray[]默认选择菜单项 key 值基本用法
routerBooleanfalse是否启用vue-router模式。启用该模式会在激活导航时以 key 作为 path 进行路由跳转-
disable-overflow-styleBooleanfalse是否禁用宽度过小时菜单的省略样式-
事件类型说明跳转 Demo
select(e: {type: 'select', key: string, el: HTMLElement, e: PointerEvent})=>void选中菜单项时触发该事件,被禁用的选项不会被触发取消多选
deselect(e: {type: 'deselect', key: string, el: HTMLElement, e: PointerEvent})=>void取消选中时触发该事件,如果菜单不是多选菜单不会被触发取消多选
submenu-change(e: {type: 'submenu-change', state: boolean, key: string, el: HTMLElement})=>void子菜单状态被更改时会触发取消多选
参数类型默认说明跳转 Demo
disabledbooleanfalse是否禁用-
keystring''菜单项的 key 值,需唯一-
hrefstring''单击菜单项后跳转的页面基本用法
routeobject-Vue Router 路径对象-
参数类型默认说明跳转 Demo
titleString''子菜单标题基本用法
disabledbooleanfalse是否禁用子菜单-
插槽名说明
icon用于定义菜单项的 icon
插槽名说明
icon用于定义子菜单标题的 icon
export type menuMode = 'vertical' | 'horizontal';
Contributors