Vuetify Tab Tips for the Lazy

This is probably not useful to Vue-masters, but for those of us who have a hard time remembering whether it's data() or data: (), this might be useful. 

A few things to remember when working with Vue tabs: 

  • Routes are just JSON objects
  • JSON objects are importable
  • JSON objects are iterable
  • Vuetify tabs have a "to" parameter

Recently, creating the boring parts of a web application (Settings, admin tools, etc.) I found I was repeating myself a ton in building tabbed router interfaces for those components. Adding the route, then adding it to the UI quickly became tiresome until I remembered that I'd recently refactored my routes into modules, so that my base Router object looks like this: 

import Router from 'vue'
import admin_routes from '@/components/Admin/routes'
import setting_routes from '@/components/Settings/routes'

const baseRoutes = [
  {
    path: '/',
    name: 'home',
    component: Home,
  },
  { ... }
]

const routes = baseRoutes.concat(admin_routes).concat(setting_routes);

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
}]

The 'settings' and 'admin' routes above there are just objects as well, which means that instead of creating a tab for each route, I can just import the routes and iterate through them. A given implementation might look like this: 

  import settingRoutes from './routes';

  export default {
    tabs: [],
    created() {
      settingRoutes[0]["children"].forEach((route) => {
        if(route.name !== 'default') 
          this.tabs.push(route);
      })
    }

And of course this works, but route names can be boring. Where you might want to display 'Danger Zone' as the tab text for a component whose route has the name 'danger-zone', it's worth remembering that routes are just objects, and you can dump new attributes into them if you like. 

So, for my 'settingRoutes' module, I made a few changes from the baseRoutes, and it looks approximately like this. 

export default [
  {
    path: '/settings',
    name: 'settings',
    component: Index,
    children: [
      {
        name: 'account',
        path: '/settings/account',
        displayName: 'Account',
        component: Account
      },
      {
        name: 'notifications',
        path: '/settings/notifications',
        displayName: 'Notifications',
        component: Notifications
      },
      {
        name: 'mydata',
        path: '/settings/mydata',
        displayName: 'My Data',
        component: MyData
      }, 
      {
        name: 'danger',
        path: '/settings/danger',
        displayName: 'Danger Zone',
        color: 'red',
        component: Danger
      }, 
      {
        name: 'default',
        path: '/settings/',
        component: Account
      }
    ]
  }
];

After that, you can use the extra properties when displaying your tabs (Vuetify or otherwise) and end up with something that looks like this: 

<v-tabs color="transparent" slider-color="#F9611B">
  <v-tab v-for="tab in tabs" :key="tab.name" :to="tab.path">
    {{ tab.displayName }}
  </v-tab>
</v-tabs>

<v-container fluid>
  <router-view></router-view>
</v-container>