Vue router link working only after refresh

I am updating navigation links based on current user login status. So if user is not logged in then show register and login links. if user is logged in then show dashboard and logout links. When I log in using login form then the links change in the navigation bar but when I click on “logout” link, it doesn’t work. Means it simply don’t do anything when I click logout. Not even an error on console.

Now if I refresh the page and then click on “Logout” then it works and logs out the user properly.

Any idea how to fix this issue?

Below is the code :

<ul class="navbar-nav ml-auto">

    <router-link tag="li" active-class="active"
        :to="{ name: 'login' }"
        v-if="!this.$store.getters.isAuthenticated">
        <a href="#" class="nav-link">Login</a>
    </router-link>

    <router-link tag="li" active-class="active"
        :to="{ name: 'register' }"
        v-if="!this.$store.getters.isAuthenticated">
        <a href="#" class="nav-link">Register</a>
    </router-link>

    <router-link tag="li" active-class="active"
        :to="{ name: 'dashboard' }"
        v-if="this.$store.getters.isAuthenticated">
        <a href="#" class="nav-link">Dashboard</a>
    </router-link>

    <router-link tag="li" active-class="active"
        :to="{ name: 'logout' }"
        v-if="this.$store.getters.isAuthenticated">
        <a href="#" class="nav-link">Logout</a>
    </router-link>

</ul>

Below is the router.js code

export default new Router({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'home',
            component: () => import('./views/Home.vue'),
        },
        {
            path: '/company/login',
            name: 'login',
            component: () => import('./views/Company/Login.vue'),
            meta: {
                forVisitor: true
            }
        },
        {
            path: '/company/register',
            name: 'register',
            component: () => import('./views/Company/Register.vue'),
            meta: {
                forVisitor: true
            }
        },
        {
            path: '/company/logout',
            name: 'logout',
            component: () => import('./views/Company/Logout.vue')
        },
        {
            path: '/dashboard',
            name: 'dashboard',
            component: () => import('./views/Company/Dashboard.vue'),
            meta: {
                forAuth: true
            }
        }
    ]
})

And here is the code from main.js file

// navigation guard
router.beforeEach(
    (to, from, next) => {
        if(to.matched.some(record => record.meta.forVisitor)){
            if(store.getters.isAuthenticated){
                next({
                    name: "dashboard"
                })
            } else next()
        }
        else if(to.matched.some(record => record.meta.forAuth)){
            if(! store.getters.isAuthenticated){
                next({
                    name: "login"
                })
            } else next()
        }
        else {
            next()
        }
    }
)

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

Is it just the logout link?

I wonder if the pre-existing href="#" is causing your issue. The standard format for a wrapped anchor is: <a>.

<ul class="navbar-nav ml-auto">

    <router-link tag="li" active-class="active"
        :to="{ name: 'login' }"
        v-if="!$store.getters.isAuthenticated">
        <a class="nav-link">Login</a>
    </router-link>

    <router-link tag="li" active-class="active"
        :to="{ name: 'register' }"
        v-if="!$store.getters.isAuthenticated">
        <a class="nav-link">Register</a>
    </router-link>

    <router-link tag="li" active-class="active"
        :to="{ name: 'dashboard' }"
        v-if="$store.getters.isAuthenticated">
        <a class="nav-link">Dashboard</a>
    </router-link>

    <router-link tag="li" active-class="active"
        :to="{ name: 'logout' }"
        v-if="$store.getters.isAuthenticated">
        <a class="nav-link">Logout</a>
    </router-link>

</ul>

Btw, you can set the default active-class using the linkActiveClass option.

I figured even after removing the href="#" from tag was causing same issue. I just turned it into normal tag instead of tag=“li”. Like this

<router-link
class="nav-link"
active-class="active"
v-if="isAuthenticated"
to="{ name: 'logout' }"
>
Logout
</router-link>