TheProphet
TheProphet

Reputation: 103

Watch changes in $route object - Vue Router

I'm doing a project of small CRM. In the login form, I have a component that shows an alert message when email or password is incorrect. When someone is trying to login incorrectly, then type the correct info and then logout, the message still appears unless the page is refreshed.

I tried to solve that within watch by accessing $route, so every time the route is changed, I clear the state of the message. Alert.vue:

<template>
 <div :class="'alert ' + alert.type">{{alert.message}}</div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

export default {
 computed: mapState({
        alert: state => state.alert
    }),
methods: mapActions({
        clearAlert: 'alert/clear' 
    }),
    watch: {
        $route (to, from){
            console.log('inside $rout');
            this.clearAlert();
        }
    }

};
</script>

main.js:

import Vue from 'vue';

import { store } from './_store';
import { router } from './_helpers';
import App from './components/App';
import './css/main.css';

new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
});

router.js:

import Vue from 'vue';
import Router from 'vue-router';

import Dashboard from '../components/Dashboard.vue';
import LoginPage from '../components/LoginPage.vue';
import UserPage from '../components/UserPage.vue';

Vue.use(Router);

export const router = new Router({
  mode: 'history',
  routes: [
    { path: '/app', component: Dashboard },
    { path: '/login', component: LoginPage },
    { path: '/app/user-info', component: UserPage },

    { path: '*', redirect: '/app' }
 ]
});

 router.beforeEach((to, from, next) => {
 const allowedPages = ['/login'];
 const authRequired = !allowedPages.includes(to.path);
 const loggedIn = localStorage.getItem('user');

 if (authRequired && !loggedIn) {
   return next('/login');
 }

 next();
})

I tried to do both methods in documentation https://router.vuejs.org/guide/essentials/dynamic-matching.html

For some reason, the $route isn't recognized & I can't access it. I should also mention that in my main.js I import the router.js file which imports Router from 'vue-router' & instantiates it, so $route should be accessible from all components. can someone shed some light on why?

link to my project: repo

Upvotes: 4

Views: 3560

Answers (1)

tony19
tony19

Reputation: 138656

The $route watcher setup you have is correct, and your component has access to $route, as can be seen if you log it in mounted().

The problem is that the watcher is in Alert.vue, which is a component that is on a page being navigated away from, so it gets destroyed, preventing the watcher being invoked. If you move the $route watcher to a component that is always kept alive (e.g., App.vue), you'll see that it works correctly.

Upvotes: 4

Related Questions