Vue3中如何实现打开一个下拉菜单时关闭另一个(无插件)
你的问题出在只用了一个布尔值open控制所有下拉菜单的显示状态,导致点击任意菜单都会同时切换所有下拉的开关。要实现「打开一个自动关闭另一个」的效果,我们可以改成记录当前打开的菜单ID,具体修改如下:
修改后的完整代码
Template 部分
<template> <ul class="menu"> <li v-for="menu in menus" :key="menu.id"> <button class="button is-white" @click="toggle($event, menu.id)"> {{ menu.name }} <ion-icon name="chevron-down-outline"></ion-icon> </button> <div class="dropdown" v-show="currentOpenId === menu.id"> <router-link to="/" v-for="item in menu.subMenu" :key="item"> <div class="options"> {{ item }} </div> </router-link> </div> </li> </ul> </template>
Script 部分
export default { data() { return { currentOpenId: null, // 改为记录当前打开的菜单ID,初始为null menus: [ { id: 1, name: 'My Profile', subMenu: ['Dashboard', 'My Profile', 'Logout'] }, { id: 2, name: 'My Orders', subMenu: ['Order'] } ], } }, created() { window.addEventListener("click", this.close); }, beforeDestroy() { window.removeEventListener("click", this.close); }, methods: { toggle(e, menuId) { e.stopPropagation(); // 阻止事件冒泡到window,避免刚打开就被关闭 // 如果当前菜单已打开则关闭,否则切换为该菜单(自动关闭其他) this.currentOpenId = this.currentOpenId === menuId ? null : menuId; }, close() { this.currentOpenId = null; // 点击外部关闭所有菜单 } } }
核心修改说明
- 状态变量替换:用
currentOpenId替代原来的open,通过记录菜单ID精准控制单个下拉的显示,打开新菜单时自动覆盖旧ID,实现「关闭其他菜单」的效果。 - Toggle 方法优化:传递菜单ID和事件对象,点击按钮时判断当前菜单状态并切换;同时阻止事件冒泡,避免触发window的click事件导致菜单刚打开就关闭。
- 显示条件调整:下拉菜单的
v-show改为判断currentOpenId是否等于当前菜单ID,确保只有目标菜单的下拉会显示。 - 列表渲染规范:给
router-link的v-for添加:key属性,符合Vue的列表渲染要求,避免控制台警告。
内容的提问来源于stack exchange,提问作者Youmi Youminem
相关产品推荐
相关产品推荐

