Menu
Must feed.
Basic Usage
Organize the menu structure through Menu, MenuItem, MenuGroup, and Submenu components.
When MenuItem receives the href or route parameter, it will be rendered as an <a> tag or as a Vue Router RouterLink component.
WARNING
The href and route properties will be directly rendered into the <a> tag. If values such as javascript:alert(1) or malicious URLs are passed, this may lead to XSS or open redirect vulnerabilities.
<template>
<px-menu :default-active="'Home'">
<px-menu-item index="Home" href="/pixelium-design/">
Home
<template #icon>
<IconHome></IconHome>
</template>
</px-menu-item>
<px-submenu index="Components" label="Components">
<template #icon>
<IconBars></IconBars>
</template>
<px-menu-item index="Button">
Button
<template #icon>
<IconArrowAltCircleUp></IconArrowAltCircleUp>
</template>
</px-menu-item>
<px-menu-item index="Input">
Input
<template #icon>
<IconPencil></IconPencil>
</template>
</px-menu-item>
</px-submenu>
<px-menu-group index="More" label="More">
<px-menu-item index="About">
About
<template #icon>
<IconLink></IconLink>
</template>
</px-menu-item>
<px-menu-item
index="Github"
href="https://github.com/shika-works/pixelium-design"
target="_blank"
>
Github
<template #icon>
<IconGithub></IconGithub>
</template>
</px-menu-item>
</px-menu-group>
</px-menu>
</template>
<script setup lang="ts">
import {
IconHome,
IconArrowAltCircleUp,
IconPencil,
IconGithub,
IconLink,
IconBars
} from '@pixelium/web-vue/icon-hn/es'
</script>Horizontal Menu
When direction is set to "horizontal", a horizontal menu is displayed. When ellipsis is true, overflowing menu items are automatically collapsed into a "..." submenu.
- ...
<template>
<px-menu direction="horizontal" :ellipsis="true">
<px-menu-item :key="i" :index="i" v-for="i in 15">Item {{ i }}</px-menu-item>
</px-menu>
</template>Collapsed Sidebar Mode
Use collapsed for sidebars to show compact UI.
- Help
<template>
<div>
<px-switch v-model="collapsed" inactive-tip="Expanded" active-tip="Collapsed"></px-switch>
<px-menu :collapsed="collapsed" :default-active="1" style="margin-top: 8px">
<px-menu-item index="Overview">
Overview
<template #icon>
<IconGrid></IconGrid>
</template>
</px-menu-item>
<px-submenu index="Components" label="Components">
<template #icon>
<IconBars></IconBars>
</template>
<px-menu-item index="Input">
Input
<template #icon>
<IconPencil></IconPencil>
</template>
</px-menu-item>
<px-menu-item index="Search">
Search
<template #icon>
<IconSearch></IconSearch>
</template>
</px-menu-item>
</px-submenu>
<px-menu-group index="Help" label="Help">
<px-menu-item index="Document">
Document
<template #icon>
<IconFolder></IconFolder>
</template>
</px-menu-item>
<px-menu-item index="AI">
AI
<template #icon>
<IconRobot></IconRobot>
</template>
</px-menu-item>
</px-menu-group>
</px-menu>
</div>
</template>
<script setup lang="ts">
import {
IconGrid,
IconPencil,
IconSearch,
IconRobot,
IconFolder,
IconBars
} from '@pixelium/web-vue/icon-hn'
import { ref } from 'vue'
const collapsed = ref(true)
</script>Groups & Submenus
Combine MenuGroup and Submenu for complex nested menus.
- Undead
- Hero
- Death Knight
- Lich
- Unit
- Crypt
- Ghoul
- Crypt Fiend
- Boneyard
- Frost Wyrm
<template>
<px-menu>
<px-menu-group index="Undead" label="Undead">
<px-submenu index="Hero" label="Hero">
<px-menu-item index="Death Knight">Death Knight</px-menu-item>
<px-menu-item index="Lich">Lich</px-menu-item>
</px-submenu>
<px-submenu index="Unit" label="Unit">
<px-submenu index="Crypt" label="Crypt">
<px-menu-item index="Ghoul">Ghoul</px-menu-item>
<px-menu-item index="Crypt Fiend">Crypt Fiend</px-menu-item>
</px-submenu>
<px-submenu index="Boneyard" label="Boneyard">
<px-menu-item index="Frost Wyrm">Frost Wyrm</px-menu-item>
</px-submenu>
</px-submenu>
</px-menu-group>
</px-menu>
</template>Emphasized Menu
Set the Menu dark attribute to true to enable high-contrast dark mode.
- Home
- Components
- Button
- Input
- More
- About
- Github
<template>
<px-menu :default-active="'Home'" dark>
<px-menu-item index="Home">
Home
<template #icon>
<IconHome></IconHome>
</template>
</px-menu-item>
<px-submenu index="Components" label="Components">
<template #icon>
<IconBars></IconBars>
</template>
<px-menu-item index="Button">
Button
<template #icon>
<IconArrowAltCircleUp></IconArrowAltCircleUp>
</template>
</px-menu-item>
<px-menu-item index="Input">
Input
<template #icon>
<IconPencil></IconPencil>
</template>
</px-menu-item>
</px-submenu>
<px-menu-group index="More" label="More">
<px-menu-item index="About">
About
<template #icon>
<IconLink></IconLink>
</template>
</px-menu-item>
<px-menu-item index="Github">
Github
<template #icon>
<IconGithub></IconGithub>
</template>
</px-menu-item>
</px-menu-group>
</px-menu>
</template>
<script setup lang="ts">
import {
IconHome,
IconArrowAltCircleUp,
IconPencil,
IconGithub,
IconLink,
IconBars
} from '@pixelium/web-vue/icon-hn/es'
</script>Options Property
The options property of Menu is used to directly pass in options, which can be used for quick creation of simple menus. The string value of the option and the index field of the option serve as unique identifiers for the menu sub-components. It is recommended to ensure their uniqueness.
<template>
<px-space direction="vertical">
<px-menu :options="optionsHorizontal" direction="horizontal"> </px-menu>
<px-menu :options="optionsVertical"> </px-menu>
</px-space>
</template>
<script setup lang="ts">
import {
IconHome,
IconArrowAltCircleUp,
IconPencil,
IconGithub,
IconLink,
IconBars
} from '@pixelium/web-vue/icon-hn/es'
import { h, ref } from 'vue'
const optionsVertical = ref([
{
label: 'Home',
index: 'Home',
href: '/pixelium-design/',
icon: h(IconHome)
},
{
label: 'Components',
index: 'Components',
icon: h(IconBars),
type: 'submenu',
children: [
{
label: 'Button',
index: 'Button',
icon: h(IconArrowAltCircleUp)
},
{
label: 'Input',
index: 'Input',
icon: h(IconPencil)
}
]
},
{
label: 'More',
index: 'More',
type: 'group',
children: [
{
label: 'About',
index: 'About',
icon: h(IconLink)
},
{
label: 'Github',
index: 'Github',
href: 'https://github.com/shika-works/pixelium-design',
target: '_blank',
icon: h(IconGithub)
},
'Contact us'
]
}
])
const optionsHorizontal = ref([
{
label: 'Home',
index: 'Home',
href: '/pixelium-design/',
icon: h(IconHome)
},
{
label: 'Components',
index: 'Components',
icon: h(IconBars),
type: 'submenu',
children: [
{
label: 'Form',
type: 'submenu',
children: [
{
label: 'Button',
index: 'Button',
icon: h(IconArrowAltCircleUp)
},
{
label: 'Input',
index: 'Input',
icon: h(IconPencil)
}
]
}
]
},
{
label: 'More',
index: 'More',
type: 'submenu',
children: [
{
label: 'Link',
index: 'Link',
type: 'group',
children: [
{
label: 'About',
index: 'About',
icon: h(IconLink)
},
{
label: 'Github',
index: 'Github',
href: 'https://github.com/shika-works/pixelium-design',
target: '_blank',
icon: h(IconGithub)
},
'Contact us'
]
}
]
}
])
</script>Controlled Menu
Control the selected menu and expanded menus by passing active and expanded. Supports v-model. If not passed or set to undefined, it operates in uncontrolled mode. In this case, default values can be set using defaultActive and defaultExpanded.
- Home
- Features
- One
- Two
<template>
<div>
<px-menu v-model:active="active" v-model:expanded="expanded">
<px-menu-item index="1">Home</px-menu-item>
<px-submenu index="2" label="Features">
<px-menu-item index="2-1">One</px-menu-item>
<px-menu-item index="2-2">Two</px-menu-item>
</px-submenu>
</px-menu>
<div style="margin-top: 12px">Active: {{ active }} | Expanded: {{ expanded }}</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const active = ref('1')
const expanded = ref(['2'])
</script>API
MenuProps
| Attribute | Type | Optional | Default | Description | Version |
|---|---|---|---|---|---|
| direction | 'horizontal' | 'vertical' | True | 'vertical' | Orientation of the menu. | 0.1.0 |
| dark | boolean | True | false | Whether the menu uses dark mode. | 0.1.0 |
| active | number | string | symbol | null | True | | Activated menu item. Supports controlled mode via v-model. | 0.1.0 |
| defaultActive | number | string | symbol | null | True | | Default value for the activated menu item in uncontrolled mode. | 0.1.0 |
| expanded | (number | string | symbol)[] | null | True | | Expanded submenus. Supports controlled mode via v-model. | 0.1.0 |
| defaultExpanded | (number | string | symbol)[] | null | True | | Default value for expanded submenus in uncontrolled mode. | 0.1.0 |
| collapsed | boolean | True | false | Whether the vertical menu is collapsed. | 0.1.0 |
| submenuMode | 'inline' | 'popover' | True | 'inline' | Display mode for submenus. This value will be used if the submenu's own mode is not set. | 0.1.0 |
| submenuTrigger | 'hover' | 'click' | True | 'hover' | Trigger method for submenu popups. This value will be used if the submenu's own trigger is not set. | 0.1.0 |
| indent | number | True | 16 | Indentation for each menu level. | 0.1.0 |
| ellipsis | boolean | True | true | Whether overflowing items in a horizontal menu are collapsed into a "..." submenu. | 0.1.0 |
| options | (string | MenuOption | MenuGroupOption | SubmenuOption)[] | True | | Options for creating menu sub-components, effective when the default slot is not passed. | 0.1.0 |
MenuEvents
| Event | Parameter | Description | Version |
|---|---|---|---|
| update:active | value: number | string | symbol | Callback when active updates. | 0.1.0 |
| update:expend | value: (number | string | symbol)[] | 0.1.0 | |
| select | index: number | string | symbol, event: MouseEvent | Callback when a menu item is selected. | 0.1.0 |
| expandChange | value: (number | string | symbol)[], event: MouseEvent | Callback when expanded submenus change. | 0.1.0 |
| expand | index: number | string | symbol, event: MouseEvent | Callback triggered when a submenu expands. | 0.1.0 |
| fold | index: number | string | symbol, event: MouseEvent | Callback triggered when a submenu folds. | 0.1.0 |
MenuSlots
| Slot | Parameter | Description | Version |
|---|---|---|---|
| default | | Child components that make up the menu. | 0.1.0 |
MenuItemProps
| Attribute | Type | Optional | Default | Description | Version |
|---|---|---|---|---|---|
| label | string | True | | Text label. | 0.1.0 |
| index | number | string | symbol | False | | Unique identifier. The index property of MenuItem and Submenu components must not be duplicated. | 0.1.0 |
| disabled | boolean | True | false | Whether it is disabled. | 0.1.0 |
| route | string | object | True | | 0.1.0 | |
| href | string | True | | The href attribute of the <a> tag. When a href parameter is passed, it will render the text label as an <a> tag. | 0.1.0 |
| target | string | True | | The target attribute of the <a> tag. | 0.1.0 |
MenuItemSlots
| Slot | Parameter | Description | Version |
|---|---|---|---|
| default | | Text label. | 0.1.0 |
| icon | | Icon. | 0.1.0 |
SubmenuProps
| Attribute | Type | Optional | Default | Description | Version |
|---|---|---|---|---|---|
| label | string | True | | Text label. | 0.1.0 |
| index | number | string | symbol | False | | Unique identifier. The index property of MenuItem and Submenu components must not be duplicated. | 0.1.0 |
| disabled | boolean | True | false | Whether it is disabled. | 0.1.0 |
| mode | boolean | True | | Display mode for the submenu. inline renders it as an inline dropdown, popover renders it in a popup window. The inline value only takes effect within vertical menus and non-popup submenus. | 0.1.0 |
| trigger | boolean | True | | Trigger method for the submenu popup. | 0.1.0 |
| popoverProps | Omit<PopoverProps, 'visible' | 'defaultVisible' | 'content'> & EmitEvent<PopoverEvents> | True | | Properties for the internal Popover component. | 0.1.0 |
SubmenuSlots
| Slot | Parameter | Description | Version |
|---|---|---|---|
| default | | Child components that make up the menu. | 0.1.0 |
| label | | Text label. | 0.1.0 |
| icon | | Icon. | 0.1.0 |
MenuGroupProps
| Attribute | Type | Optional | Default | Description | Version |
|---|---|---|---|---|---|
| label | string | True | | Text label. | 0.1.0 |
MenuGroupSlots
| Slot | Parameter | Description | Version |
|---|---|---|---|
| default | | Child components that make up the menu. | 0.1.0 |
| label | | Text label. | 0.1.0 |
MenuOption, MenuGroupOption, SubmenuOption
export interface MenuOption extends NavigationOption {
disabled?: boolean
href?: string
route?: string | object
target?: string
icon?: () => ValidVNodeContent
}
export interface MenuGroupOption extends NavigationOption {
children: (string | MenuOption | MenuGroupOption | SubmenuOption)[]
type: 'group'
}
export interface SubmenuOption extends NavigationOption {
children: (string | MenuOption | MenuGroupOption | SubmenuOption)[]
disabled?: boolean
type: 'submenu'
icon?: () => ValidVNodeContent
}
export interface NavigationOption {
index: string | number | symbol
label?: string
}
export type ValidVNodeContent = (...args: any[]) => VNode | JSX.Element2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
EmitEvent
export type EmitEvent<T extends Record<string, any>> = {
[K in keyof T as `on${Capitalize<K & string>}`]?: (...args: T[K]) => void
}2
3