Why isn't router.currentRoute.path reactive?

Viewed 9963

I have an app which is contained in this div:

<div id="app" v-bind:style='{backgroundColor: backgroundColor}'>
  ... the app ...
</div>

The routing is done following the example in the documentation (this is a webpack project):

import Vue from 'vue/dist/vue.js'
import VueRouter from 'vue-router'
import ComponentOne from './component1.vue'
import ComponentTwo from './component2.vue'

Vue.use(VueRouter)

const routes = [{
        path: '/foo',
        component: ComponentOne
    },
    {
        path: '/bar',
        component: ComponentTwo
    }
]

const router = new VueRouter({
    routes // short for `routes: routes`
})

const app = new Vue({
    router,
    data: {
        day: "Monday"
    },
    computed: {
        backgroundColor: function () {
            console.log(JSON.stringify(router.currentRoute))
            if (router.currentRoute.path == "/foo") {
                return "green"
            } else {
                return "blue"
            }
        }
    }
}).$mount('#app')

I wanted the background to be dependent on the current route (router.currentRoute.path).

But, the solution above does not work, because router.currentRoute.path is not detected by the Vue instance as having changed (is not reactive).

What is the correct way to access the dynamic router data from within the Vue instance?

2 Answers

I found on Vue's documentation page that tracks the router using watch for transition animations. Not sure if this is a best practice but you can use to.path or from.path to grab the path instead.

// then, in the parent component,
// watch the `$route` to determine the transition to use
watch: {
  '$route': (to, from) => {
    const toDepth = to.path.split('/').length
    const fromDepth = from.path.split('/').length
    this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
  }
}
Related