vue实现下拉菜单
实现下拉菜单的基本结构
使用 Vue 的 v-show 或 v-if 控制下拉菜单的显示与隐藏。通过点击按钮触发状态切换。

<template>
<div class="dropdown">
<button @click="toggleDropdown">点击展开</button>
<ul v-show="isOpen">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
isOpen: false
};
},
methods: {
toggleDropdown() {
this.isOpen = !this.isOpen;
}
}
};
</script>
<style>
.dropdown {
position: relative;
display: inline-block;
}
.dropdown ul {
position: absolute;
list-style: none;
padding: 0;
margin: 0;
border: 1px solid #ccc;
}
.dropdown li {
padding: 8px 16px;
cursor: pointer;
}
.dropdown li:hover {
background-color: #f5f5f5;
}
</style>
添加点击外部关闭功能
通过监听全局点击事件,判断点击目标是否在下拉菜单外部,实现自动关闭。

<template>
<div class="dropdown" ref="dropdown">
<button @click.stop="toggleDropdown">点击展开</button>
<ul v-show="isOpen">
<li>选项1</li>
<li>选项2</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
isOpen: false
};
},
methods: {
toggleDropdown() {
this.isOpen = !this.isOpen;
},
closeDropdown(event) {
if (!this.$refs.dropdown.contains(event.target)) {
this.isOpen = false;
}
}
},
mounted() {
document.addEventListener('click', this.closeDropdown);
},
beforeDestroy() {
document.removeEventListener('click', this.closeDropdown);
}
};
</script>
使用 Vue 组件封装
将下拉菜单封装为可复用的组件,通过插槽(slot)支持自定义内容。
<!-- Dropdown.vue -->
<template>
<div class="dropdown" ref="dropdown">
<div @click.stop="toggleDropdown">
<slot name="trigger"></slot>
</div>
<div v-show="isOpen" class="dropdown-content">
<slot name="content"></slot>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isOpen: false
};
},
methods: {
toggleDropdown() {
this.isOpen = !this.isOpen;
},
closeDropdown(event) {
if (!this.$refs.dropdown.contains(event.target)) {
this.isOpen = false;
}
}
},
mounted() {
document.addEventListener('click', this.closeDropdown);
},
beforeDestroy() {
document.removeEventListener('click', this.closeDropdown);
}
};
</script>
调用封装组件
在父组件中传入自定义的触发器和下拉内容。
<template>
<Dropdown>
<template v-slot:trigger>
<button>自定义触发器</button>
</template>
<template v-slot:content>
<ul>
<li>自定义选项1</li>
<li>自定义选项2</li>
</ul>
</template>
</Dropdown>
</template>
<script>
import Dropdown from './Dropdown.vue';
export default {
components: { Dropdown }
};
</script>
注意事项
- 事件冒泡处理:使用
@click.stop阻止触发器点击事件冒泡,避免触发外部关闭逻辑。 - 性能优化:在组件销毁时移除全局事件监听,避免内存泄漏。
- 无障碍支持:为下拉菜单添加
aria-expanded属性,增强屏幕阅读器兼容性。






