본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

Menu 메뉴

원문 보기 위키 갱신

Menu 컴포넌트는 주로 내비게이션에 사용해요.

출처: 문서

본문

언제 사용하나요

여러 옵션을 모아서 정리하고, 배치하고, 보여줘야 할 때 사용해요.

기본 사용법

:::demo 화면 크기가 너무 작으면 말줄임표가 나타나요

<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 슬롯을 사용해 메뉴에 아이콘을 정의할 수 있고, CSS로 슬롯을 원하는 대로 꾸밀 수도 있어요.

:::demo

<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>

:::

세로 메뉴

세로 메뉴는 주로 관리자(백오피스) 화면에서 널리 쓰이고, 서브메뉴를 메뉴 안에 중첩할 수 있어요.

:::demo

<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를 설정하면 펼쳐질 서브메뉴 항목을 바꿀 수 있어요.

:::demo

<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>

:::

루트 서브메뉴 하나만 펼치기

:::demo 서브메뉴 상태 변경 이벤트로 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>

:::

메뉴 축소

:::demo

<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 이벤트가 발생해요.

:::demo

<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 같은 파라미터는 모두 반응형이에요.

:::demo

<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 링크
width String '' 메뉴 너비 제어용 반응형 파라미터
collapsed Boolean false 메뉴 접힘 여부 결정용 메뉴 접기
collapsed-indent Number 24 접었을 때 아이콘과 좌우 테두리 사이 거리 메뉴 접기
multiple Boolean false 다중 선택 가능 여부 다중 선택 해제
mode menuMode 'vertical' 메뉴 타입 기본 사용법
open-keys Array [] 기본 펼침 하위 메뉴 key 값 기본 펼치기
default-select-keys Array [] 기본 선택 메뉴 항목 key 값 기본 사용법
router Boolean false vue-router 모드 사용 여부. 사용 시 네비게이션 활성화 때 key를 path로 라우팅 이동 -
disable-overflow-style Boolean false 너비가 좁을 때 메뉴 생략(ellipsis) 스타일 비활성화 여부 -
이벤트 타입 설명 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 링크
disabled boolean false 비활성화 여부 -
key string '' 메뉴 항목 key 값. 유일해야 함 -
href string '' 메뉴 항목 클릭 후 이동할 페이지 기본 사용법
route object - Vue Router 경로 객체 -
파라미터 타입 기본값 설명 Demo 링크
title String '' 하위 메뉴 제목 기본 사용법
disabled boolean false 하위 메뉴 비활성화 여부 -
슬롯명 설명
icon 메뉴 항목 icon 정의용
슬롯명 설명
icon 하위 메뉴 제목 icon 정의용
export type menuMode = 'vertical' | 'horizontal';

더 알아보기 (Learn more)

mode로 가로·세로 메뉴를 고르고, collapsed로 접기, open-keys로 기본 펼침, multiple로 다중 선택까지 설정할 수 있어요. router 모드를 켜면 key를 path로 삼아 vue-router 라우팅까지 연결돼요.