Dropdown
Dropdown menu component
Project Status
Detailed changes for each release are documented in Changelog
If you are using vue 2.x version, please use v-dropdown 2.x version instead
Installation
Install the v-dropdown component into your project:
npm i v-dropdownyarn add v-dropdownpnpm add v-dropdownComponents
v-dropdown provides the following components
- Dropdown The main container of the dropdown
- DropdownTrigger dropdown built-in button trigger
- DropdownContent dropdown content container
Basic Usage
<Dropdown @visible-change="change">
<!-- trigger element -->
<template #trigger>
<!-- built-in trigger button -->
<DropdownTrigger />
</template>
<!-- contents display in dropdown -->
<DropdownContent>
<div>
some contents
</div>
</DropdownContent>
</Dropdown>import { Dropdown, DropdownContent, DropdownTrigger } from 'v-dropdown'
function change(val) {
console.log(val)
}Examples
Quick Usage
The Dropdown component uses click trigger by default
<Dropdown>
<DropdownContent>
<div>some contents</div>
</DropdownContent>
</Dropdown>Hover Activation
Open dropdown by hovering over trigger area
<Dropdown trigger="hover">
<template #trigger>
<DropdownTrigger>Hover me</DropdownTrigger>
</template>
...
</Dropdown>Context Menu Activation
Right-click trigger area to open dropdown
<Dropdown
trigger="contextmenu"
block
>
<template #trigger>
<div
style="height: 10rem;"
class="
d-flex align-items-center justify-content-center
bg-light rounded-3 px-3 py-1 fs-1 text-body-secondary w-100
"
>Mouse right click me</div>
</template>
...
</Dropdown>Toggle Cycle
Disable toggle cycle when clicking trigger
<Dropdown :toggle="false">
...
</Dropdown>Disabled State
<Dropdown :disabled="true">
...
</Dropdown>Manual Mode
Only opens dropdown when input value is "3"
<Dropdown
:manual="true"
ref="dropdown"
>
<template #trigger>
<input
type="text"
@input="inputChange"
/>
</template>
...
</Dropdown>import { ref } from 'vue'
const dropdown = ref(null)
function inputChange(e) {
if (e.target.value === '3') {
dropdown.value.open()
} else {
if (dropdown.value.visible) {
dropdown.value.close()
}
}
}Alignment Direction
Dropdown alignment relative to trigger
<Dropdown align="center">
...
</Dropdown>Style Customization
<Dropdown>
<template #trigger>
<DropdownTrigger rounded="pill" />
</template>
<DropdownContent
:border="false"
rounded="medium"
>
<div>some contents</div>
</DropdownContent>
</Dropdown>Advanced styling via style or class
<Dropdown>
<template #trigger>
<DropdownTrigger class="border rounded-4 bg-primary-subtle p-2" />
</template>
<DropdownContent
style="width: 500px;background-color:rgb(255, 174, 0);"
>
<div>some contents</div>
</DropdownContent>
</Dropdown>State & Utilities
Dropdown provides component state and utility functions to slots
<Dropdown>
<template #trigger="{ visible, disabled, close }">
<DropdownTrigger />
</template>
<template #default="{ visible, disabled, close }">
<DropdownContent>
<div>visible: {{ visible }}</div>
<div>disabled: {{ disabled }}</div>
<button
class="btn btn-secondary"
@click="close"
>Close</button>
</DropdownContent>
</template>
</Dropdown>The useDropdown composable provides state and utilities:
<Dropdown>
<template #trigger>
<DropdownTrigger />
</template>
<DropdownContent>
<CustomContent />
</DropdownContent>
</Dropdown><template>
<div>
<div>visible: {{ visible }}</div>
<div>disabled: {{ disabled }}</div>
<button
class="btn btn-secondary"
@click="close"
>Close</button>
</div>
</template>
<script setup>
import { useDropdown } from 'v-dropdown'
const { visible, disabled, close } = useDropdown()
</script>Slots
Dropdown
triggerTrigger elementdefaultDropdown content
Slot scope utilities
interface DropdownUtilities {
visible: ComputedRef<boolean>
disabled: ComputedRef<boolean>
/** Adjust content position */
adjust: () => void
/** Open dropdown */
open: () => void
/** Close dropdown */
close: () => void
/** Toggle dropdown open and close */
toggleVisible: () => void
}Data status provided by the slot
<template>
<Dropdown>
<template #trigger="data: DropdownUtilities">
<button type="button">visible: {{ data.visible }}</button>
</template>
<template #default="{ visible, disabled, close }: DropdownUtilities">
<div>visible: {{ visible }}</div>
<div>disabled: {{ disabled }}</div>
<button
class="btn btn-secondary"
@click="close"
>Close</button>
</template>
</Dropdown>
</template>
<script setup lang="ts">
import type { DropdownUtilities } from 'v-dropdown'
</script>The adjust function provided by the slot is used to adjust the position of the dropdown content to align it with the trigger element
INFO
In most cases, when the position and size of the trigger and the drop-down bar content change, the component will automatically adjust the position of the drop-down bar content. Therefore, it is only recommended to use it when the position of the drop-down bar does not meet expectations in scenarios with complex business interactions
DropdownTrigger
Built-in button-style trigger component
defaultTrigger content (default: "Open")appendOpened state icon
DropdownContent
defaultDropdown content
Props
Dropdown component props
interface DropdownProps {
/**
* Dropdown alignment
* @default `left`
*/
align?: 'left' | 'center' | 'right'
/**
* Toggle visibility on repeated trigger clicks
* @default true
*/
toggle?: boolean
/**
* Manual control mode
* @default false
*/
manual?: boolean
/**
* Disabled state
* @default false
*/
disabled?: boolean
/**
* Trigger displays in full-width mode
* @default false
*/
block?: boolean
/**
* Trigger method
* @default `click`
*/
trigger?: 'click' | 'hover' | 'contextmenu'
/**
* Enable animations
* @default true
*/
animated?: boolean
/**
* Spacing between trigger and dropdown
* @default 5
*/
gap?: number
/**
* Specify target container
* @default `body`
*/
appendTo: string | HTMLElement
}DropdownContent component props
interface ContentProps {
/**
* Show border
* @default true
*/
border?: boolean
/**
* Border radius
* @default `small`
*/
rounded?: 'small' | 'medium' | 'large'
/**
* z-index value
* @default 3000
*/
zIndex?: number
}DropdownTrigger component props
interface TriggerProps {
/** Button border radius */
rounded?: 'small' | 'medium' | 'large' | 'pill' | 'circle'
}Events
visible-change
Triggered on visibility change
`visible-change`: (visible: boolean) => voidopen
Triggered when dropdown opens
open: () => voidopened
Triggered after opening animation completes
opened: () => voidclose
Triggered when dropdown closes
close: () => voidclosed
Triggered after closing animation completes
closed: () => voidAPI
Before using the plugin's API, declare a ref attribute for the component:
<template>
<Dropdown ref="dropdown" />
</template>
<script setup lang="ts">
import { ref, onMounted, useTemplateRef } from 'vue'
import { Dropdown, type DropdownUtilities } from 'v-dropdown'
// vue 3.5+
const dropdownRef = useTemplateRef<DropdownUtilities>('dropdown')
// Vue versions lower than 3.5
// const dropdownRef = ref<DropdownUtilities>()
onMounted(() => {
dropdownRef.value?.open()
})
</script>The API of the Dropdown component is consistent with the data type DropdownUtilities provided by its default and trigger slots. Please refer to Dropdown slot