Linking to a Specific Tab in Vuetify.js
By: Jarek Lipski
Tags: Nuxtjs, Web Development, UX, Vuetify, Vuejs

Linking to a Specific Tab in Vuetify.js

Store the current tab in the URL, to navigate to it from anywhere else in the app

Photo by Chiara F on Unsplash

I would like to present to you a quick tip about working with the tabs component in Vuetify.js. I sometimes need to navigate to a specific tab in the application or want to share a direct tab link with a collaborator.

In order to achieve this, we need to store the information about the current tab in the URL in the browser address bar. A canonical solution involves using nested routes, but sometimes it’s an overkill to create a separate child page for each tab. Thankfully there’s a simpler approach that I quite often end up using.

TL;DR — go straight to the final code

Simple Tabs

First let’s look at a simple tabs component example:

<template>

...

<v-card>

<v-tabs v-model="tab" background-color="grey lighten-4">

<v-tab>

One

</v-tab>

<v-tab>

Two

</v-tab>

</v-tabs> <v-tabs-items :value="tab">

<v-tab-item>

<v-card-text>

This is ONE!<br>1111111111

</v-card-text>

</v-tab-item>

<v-tab-item>

<v-card-text>

This is TWO!<br>2222222222

</v-card-text>

</v-tab-item>

</v-tabs-items>

</v-card>

...

</template> <script>

export default {

data: () => ({

tab: null

})

}

</script>

Note that we could also mix tabs with tab items in <v-tabs> component for simplicity, but I prefer to separate tabs from tab items for flexibility.

With the above code, the current tab is stored in the tab variable as an ordinal number. The problem with using this number to identify a tab is that the order of tabs can change if we add any new ones in the future.

Named Tabs

Instead of distinguishing tabs by their number, we can use a descriptive name. To achieve this we need to specify a href attribute on the tab and a value attribute on the tab item:

<v-card>

<v-tabs v-model="tab" background-color="grey lighten-4">

<v-tab href="#one">

One

</v-tab>

<v-tab href="#two">

Two

</v-tab>

</v-tabs> <v-tabs-items :value="tab">

<v-tab-item value="one">

<v-card-text>

This is ONE!<br>1111111111

</v-card-text>

</v-tab-item>

<v-tab-item value="two">

<v-card-text>

This is TWO!<br>2222222222

</v-card-text>

</v-tab-item>

</v-tabs-items>

</v-card>

Note that we need to prepend the tab name with a hash symbol in the href attribute (e.g. href="#one" ), but not in the value attribute.

Storing the Current Tab in the URL

In order to store the current tab in the URL, we will use a computed tab property with a setter. Let’s replace our data with:

computed: {

tab: {

set (tab) {

this.$router.replace({ query: { ...this.$route.query, tab } })

},

get () {

return this.$route.query.tab

}

}

}

Note that we are calling $router.replace() instead of $router.push() to avoid storing a visited tab in navigation history and to preserve the back-button functionality.

Now, when we visit the page for the first time, the URL will include the current tab as a query parameter. It will also update this parameter automatically every time we switch the tab.

One last thing — a button linking to a specific tab will simply look as follows:

<v-btn to="/page?tab=one">

Tab One

</v-btn>