I am trying to combine tabs and menus for navigation. I placed two tabs and one menu in the header, and configured vue router for them. When I click the tabs, the tab slider (the white line under the selected tab) switches correctly, but when I click the menu items, the slider doesn't move. How to manually update the slider?
This is based on the "Overflow to menu" example on the official website.
src/App.vue
:
<template>
<v-app>
<v-tabs>
<v-tab to="/1">Tab 1</v-tab>
<v-tab to="/2">Tab 2</v-tab>
<v-menu>
<template v-slot:activator="{ props }">
<v-btn v-bind="props">Tab 3</v-btn>
</template>
<v-list>
<v-list-item to="/3?item=1">Item 1</v-list-item>
<v-list-item to="/3?item=2">Item 2</v-list-item>
</v-list>
</v-menu>
</v-tabs>
<v-main>
<router-view />
</v-main>
</v-app>
</template>
src/pages/1.vue
:
<template>
/1
</template>
src/pages/2.vue
:
<template>
/2
</template>
src/pages/3.vue
:
<template>
/3 (item {{ route.query.item }})
</template>
<script lang="ts" setup>
import { useRoute } from 'vue-router';
const route = useRoute();
</script>
Screenshot: Item 1 in Tab 3 is selected, however, the tab slider is still under Tab 2.
After a lot of hard work, I finally came up with a perfect yet simple solution:
New App.vue
:
<template>
<v-app>
<v-tabs>
<v-tab to="/1">Tab 1</v-tab>
<v-tab to="/2">Tab 2</v-tab>
<v-menu>
<template v-slot:activator="{ props }">
<v-tab v-bind="props" append-icon="mdi-menu-down">Tab 3</v-tab>
</template>
<v-list>
<v-list-item to="/3?item=1" exact>Item 1</v-list-item>
<v-list-item to="/3?item=2" exact>Item 2</v-list-item>
</v-list>
</v-menu>
</v-tabs>
<v-main>
<router-view />
</v-main>
</v-app>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const selectedTab = computed({
get() {
switch (route.path) {
case '/1':
return 0;
case '/2':
return 1;
case '/3':
return 2;
default:
return 0;
}
},
set() {
// Do nothing.
}
});
</script>
Instead of intercepting the update logic of the <v-tabs>
component, I use a writable computed to rewrite the update logic and make it solely dependent on the current route.
If you can read Chinese, you can take a look at my blog, which covers more details.