Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How To Show Only One V-Menu At A Time When Clicking To Show The Menu?
In Vuetify applications, showing only one v-menu at a time when clicking requires proper state management. This prevents multiple menus from being open simultaneously and provides better user experience.
Understanding v-menu Behavior
By default, v-menu components can open independently. To ensure only one menu is visible at a time, we need to control their state using Vue's data properties and watchers.
Method 1: Using Individual State Control
This approach manages each menu's state individually and closes others when one opens:
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<v-app>
<v-container>
<div style="display: flex; gap: 20px; align-items: center;">
<v-menu
v-for="(user, index) in userInfo"
:key="index"
v-model="menuStates[index]"
@input="onMenuToggle(index, $event)"
offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" color="primary">
{{user.name}}
</v-btn>
</template>
<v-list>
<v-list-item>
<v-list-item-content>
<v-list-item-title>Favorite Car: {{user.favoritecar}}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-menu>
</div>
</v-container>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
userInfo: [
{ id: 1, name: "Alice", favoritecar: "RX100" },
{ id: 2, name: "Bob", favoritecar: "DUCATI" },
{ id: 3, name: "Charlie", favoritecar: "RANGEROVER" }
],
menuStates: [false, false, false]
};
},
methods: {
onMenuToggle(index, isOpen) {
if (isOpen) {
// Close all other menus
this.menuStates.forEach((state, i) => {
if (i !== index) {
this.$set(this.menuStates, i, false);
}
});
}
}
}
});
</script>
</body>
</html>
Method 2: Using Single Active Menu State
This cleaner approach tracks which menu is currently active using a single variable:
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<v-app>
<v-container>
<div style="display: flex; gap: 20px; align-items: center;">
<v-menu
v-for="(item, index) in menuItems"
:key="index"
:value="activeMenu === index"
@input="toggleMenu(index, $event)"
offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" :color="activeMenu === index ? 'success' : 'primary'">
{{item.label}}
</v-btn>
</template>
<v-list>
<v-list-item v-for="option in item.options" :key="option">
<v-list-item-content>
<v-list-item-title>{{option}}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-menu>
</div>
</v-container>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
activeMenu: null,
menuItems: [
{ label: "Menu 1", options: ["Option A", "Option B"] },
{ label: "Menu 2", options: ["Choice 1", "Choice 2"] },
{ label: "Menu 3", options: ["Item X", "Item Y"] }
]
};
},
methods: {
toggleMenu(index, isOpen) {
this.activeMenu = isOpen ? index : null;
}
}
});
</script>
</body>
</html>
Comparison
| Method | Data Management | Complexity | Best For |
|---|---|---|---|
| Individual State Control | Array of booleans | Medium | Complex menu interactions |
| Single Active State | Single variable | Low | Simple one-at-a-time behavior |
Key Points
- Use
v-modelor:valuewith@inputto control menu visibility - Track active menu state in Vue data
- Close other menus when one opens using event handlers
- The single active state approach is cleaner for most use cases
Conclusion
Implementing one-at-a-time v-menu behavior requires proper state management. The single active menu approach offers the cleanest solution for most applications, ensuring better user experience by preventing menu overlap.
