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>
:::
Menu 파라미터
| 파라미터 | 타입 | 기본값 | 설명 | 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) 스타일 비활성화 여부 | - |
Menu 이벤트
| 이벤트 | 타입 | 설명 | 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 |
하위 메뉴 상태 변경 시 트리거 | 다중 선택 해제 |
MenuItem 파라미터
| 파라미터 | 타입 | 기본값 | 설명 | Demo 링크 |
|---|---|---|---|---|
| disabled | boolean | false | 비활성화 여부 | - |
| key | string | '' | 메뉴 항목 key 값. 유일해야 함 | - |
| href | string | '' | 메뉴 항목 클릭 후 이동할 페이지 | 기본 사용법 |
| route | object | - | Vue Router 경로 객체 | - |
SubMenu 파라미터
| 파라미터 | 타입 | 기본값 | 설명 | Demo 링크 |
|---|---|---|---|---|
| title | String | '' | 하위 메뉴 제목 | 기본 사용법 |
| disabled | boolean | false | 하위 메뉴 비활성화 여부 | - |
MenuItem 슬롯
| 슬롯명 | 설명 |
|---|---|
| icon | 메뉴 항목 icon 정의용 |
SubMenu 슬롯
| 슬롯명 | 설명 |
|---|---|
| icon | 하위 메뉴 제목 icon 정의용 |
menu 타입 정의
menuMode
export type menuMode = 'vertical' | 'horizontal';
더 알아보기 (Learn more)
mode로 가로·세로 메뉴를 고르고, collapsed로 접기, open-keys로 기본 펼침, multiple로 다중 선택까지 설정할 수 있어요. router 모드를 켜면 key를 path로 삼아 vue-router 라우팅까지 연결돼요.