Denis Steinman
Denis Steinman

Reputation: 7799

How to get the current active route in Vue.js?

I have a trivial Vue-app:

App.vue:

<template>
  <v-app>
    <v-navigation-drawer
      app
      v-model="drawer"
      :mini-variant.sync="mini"
      permanent
      color="secondary"
      dark
    >
      <v-list-item class="px-2 user-block">
        <v-list-item-avatar>
          <div class="avatar">JL</div>
        </v-list-item-avatar>

        <v-list-item-title>John Leider</v-list-item-title>

        <v-btn icon @click.stop="mini = !mini">
          <v-icon>mdi-chevron-left</v-icon>
        </v-btn>
      </v-list-item>

      <v-divider></v-divider>

      <v-list dense>
        <v-list-item
          v-for="item in items"
          :key="item.title"
          :href="item.link"
          @click.stop="title = item.title"
        >
          <v-list-item-icon>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-item-icon>

          <v-list-item-content>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>
    <v-app-bar app light>
      <div class="d-flex align-center">IFRS 9: {{ title }}</div>

      <v-spacer></v-spacer>
    </v-app-bar>

    <v-main>
      <router-view />
    </v-main>
  </v-app>
</template>

<script lang="ts">
import Vue from 'vue'
import router from './router'

export default Vue.extend({
  name: 'App',

  created() {
    const currentPath = router.currentRoute.path
    const activeItem = this.items.find((m) => m.link === currentPath)
    console.log(activeItem?.title)
    this.title = activeItem ? activeItem.title : 'Home'
  },

  data: () => ({
    drawer: true,
    items: [
      { title: 'Home', icon: 'mdi-home', link: '/' },
      { title: 'About', icon: 'mdi-help', link: '/about' },
    ],
    mini: true,
    title: '',
  }),
})
</script>

<style lang="sass">
@import '~vuetify/src/styles/settings/_variables'

.avatar
  background-color: #FFFFFF
  color: #6D2077
  font-weight: bold
  width: 48px
  height: 48px
  line-height: 48px

.user-block
  height: 64px

@media #{map-get($display-breakpoints, 'sm-and-down')}
  .user-block
    height: 56px
</style>

router/index.ts:

import Vue from 'vue'
import VueRouter, { RouteConfig } from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes: Array<RouteConfig> = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () =>
      import(/* webpackChunkName: "about" */ '../views/About.vue'),
  },
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
})

export default router

Above in this code I try to change title value basing on the current route path but it always prints 'Home'.

What am I doing wrongly?

P.S. I'm a noobie in Vue.

Upvotes: 0

Views: 1524

Answers (1)

RoboKozo
RoboKozo

Reputation: 5062

Because this code is in App.vue, the highest level component, you should not setup the title on the created lifecycle hook. Instead you should consider setting up a 'watcher' to monitor the $route value. For example:

export default Vue.extend({
  name: "App",
  //...
  watch: {
    $route(newRouteValue) {
      console.log(newRouteValue); // {name: "About", meta: {…}, path: "/about", hash: "", query: {…}, …}
    },
  },
});

With this code, whenever the user navigates around to the different pages of your web app, the title can be updated appropriately.

Here are the official docs for watchers: https://v2.vuejs.org/v2/guide/computed.html#Watchers

Upvotes: 1

Related Questions