admin管理员组

文章数量:1192339

I have a login issue with website that uses:

  • Vue.js v2.0.3
  • vue-router v2.0.1
  • vuex v0.8.2

In routes.js I have a simple interceptor setup

router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!router.app.auth.isUserLoggedIn) {
        next({
            path: '/login',
            query: { redirect: to.fullPath }
        })
    } else {
        next()
    }
} else {
    next() // make sure to always call next()!
}

})

And in login.vue,which handles the login page logic after using Google API only for login succeeds I call this:

this.login(userData).then( 
    () => this.$router.push(this.redirectToAfterLogin), // Login success
    () => {} // Login failed
)


mounted: function(){
if (this.auth.isUserLoggedIn){
            // Let's just redirect to the main page
            this.$router.push(this.redirectToAfterLogins)
        }else{
            Vue.nextTick(() => {
                this.loadGooglePlatform()
            })}}


computed: {
        redirectToAfterLogin: function() {
            if (this.$route.query.redirect){
                return this.$route.query.redirect
            }else{
                return '/'
            }
        }
    }

router.js

var VueRouter = require('vue-router')

// Router setup
export const router = new VueRouter({
    linkActiveClass: "is-active",
    mode: 'history',
    saveScrollPosition: true,
    routes: [
        { path: '', name: 'root', redirect: '/home' },
        { path: '/login', name: 'login', meta: { loadingNotRequired: true }, component: require('./pages/login.vue') },
        { path: '/logout', name: 'logout', meta: { loadingNotRequired: true }, component: require('./pages/logout.vue') },
        { path: '/home', name: 'home', title: 'Home', redirect: '/home/random', component: require('./pages/home.vue'),
            children: [
                { path: 'random', name: 'random', meta: { requiresAuth: true }, title: 'Random', component: require('./pages/random.vue') }
            ]  
        }
    ]
})

// Redirect to login page if not logged In
router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        // this route requires auth, check if logged in
        // if not, redirect to login page.
        if (!router.app.auth.isUserLoggedIn) {
            next({
                path: '/login',
                query: { redirect: to.fullPath }
            })
        } else {
            next()
        }
    } else {
        next() // make sure to always call next()!
    }
})

Now here this.login is just the call to vuex, to update the logged in user.

What happens is that after login, URL changes to /home, but the DOM does not update!

Only way that successfully changed the DOM was forcing location.reload() and that is not what I want to do, as it loses my dynamically loaded G scripts in Head.

Any idea on what to do to force the view to update DOM?

NOTE: it happens only on the first login of user, if he logs out and back-in, the redirecting is fine

I have a login issue with website that uses:

  • Vue.js v2.0.3
  • vue-router v2.0.1
  • vuex v0.8.2

In routes.js I have a simple interceptor setup

router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!router.app.auth.isUserLoggedIn) {
        next({
            path: '/login',
            query: { redirect: to.fullPath }
        })
    } else {
        next()
    }
} else {
    next() // make sure to always call next()!
}

})

And in login.vue,which handles the login page logic after using Google API only for login succeeds I call this:

this.login(userData).then( 
    () => this.$router.push(this.redirectToAfterLogin), // Login success
    () => {} // Login failed
)


mounted: function(){
if (this.auth.isUserLoggedIn){
            // Let's just redirect to the main page
            this.$router.push(this.redirectToAfterLogins)
        }else{
            Vue.nextTick(() => {
                this.loadGooglePlatform()
            })}}


computed: {
        redirectToAfterLogin: function() {
            if (this.$route.query.redirect){
                return this.$route.query.redirect
            }else{
                return '/'
            }
        }
    }

router.js

var VueRouter = require('vue-router')

// Router setup
export const router = new VueRouter({
    linkActiveClass: "is-active",
    mode: 'history',
    saveScrollPosition: true,
    routes: [
        { path: '', name: 'root', redirect: '/home' },
        { path: '/login', name: 'login', meta: { loadingNotRequired: true }, component: require('./pages/login.vue') },
        { path: '/logout', name: 'logout', meta: { loadingNotRequired: true }, component: require('./pages/logout.vue') },
        { path: '/home', name: 'home', title: 'Home', redirect: '/home/random', component: require('./pages/home.vue'),
            children: [
                { path: 'random', name: 'random', meta: { requiresAuth: true }, title: 'Random', component: require('./pages/random.vue') }
            ]  
        }
    ]
})

// Redirect to login page if not logged In
router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        // this route requires auth, check if logged in
        // if not, redirect to login page.
        if (!router.app.auth.isUserLoggedIn) {
            next({
                path: '/login',
                query: { redirect: to.fullPath }
            })
        } else {
            next()
        }
    } else {
        next() // make sure to always call next()!
    }
})

Now here this.login is just the call to vuex, to update the logged in user.

What happens is that after login, URL changes to /home, but the DOM does not update!

Only way that successfully changed the DOM was forcing location.reload() and that is not what I want to do, as it loses my dynamically loaded G scripts in Head.

Any idea on what to do to force the view to update DOM?

NOTE: it happens only on the first login of user, if he logs out and back-in, the redirecting is fine

Share Improve this question edited Jul 9, 2017 at 20:31 Bert 82.4k17 gold badges203 silver badges166 bronze badges asked Oct 31, 2016 at 18:21 desicnedesicne 8612 gold badges11 silver badges23 bronze badges 7
  • in () => this.$router.push(this.redirectToAfterLogin()), // Login success, did you miss the () after redirectToAfterLogin? – JJPandari Commented Nov 3, 2016 at 13:25
  • @PanJunjie潘俊杰 hm...no, that does not seem to be the case, as it occurs in promise, and if I do so, I get Type Error TypeError: _this2.redirectToAfterLogin is not a function(…) I edited the code, to show you also mounted section, but not much happen there – desicne Commented Nov 4, 2016 at 16:12
  • redirectToAfterLogins is a computed property, not a function, () are not required. Could you show the content of your router config? – jeerbl Commented Nov 10, 2016 at 20:19
  • @jeerbl Sure, I added the conf.. – desicne Commented Nov 15, 2016 at 17:36
  • 2 @dscni Did you ever figure it out? I'd love to know the answer – nachocab Commented Jan 22, 2017 at 19:09
 |  Show 2 more comments

4 Answers 4

Reset to default 12

Not a perfect solution may be, as it is going to recreate the component but it will work for every case when having same route & needs to update the component.

Just update the <router-view/> or <router-view></router-view> with

<router-view :key="$route.fullPath"></router-view>

Vue re-uses components where possible. You should use beforeRouteUpdate to react to a route switch that uses the same component.

I have the same problem "URL changes to /home, but the DOM does not update".
In my project, the tag "transition" maked the problem.
Hope it is helpful!

Maybe you should set the redirectToAfterLogin function into methods, like this it will be recalculated each times. The computed will be modified only if used v-model changed. To stick to the meaning of the function name, I would set the router push inside.

login.vue :

mounted: function(){
   if (this.auth.isUserLoggedIn){
            // Let's just redirect to the main page
            // this.$router.push(this.redirectToAfterLogins)
            this.redirectToAfterLogins()
   }else{
            Vue.nextTick(() => {
                this.loadGooglePlatform()
            })
   }
},
// computed: {
methods: {
    this.login(userData).then( 
       // () => this.$router.push(this.redirectToAfterLogin), // Login success
       () => this.redirectToAfterLogin(), // Login success
       () => {} // Login failed
    ),
    redirectToAfterLogin: function() {
            
        if (this.$route.query.redirect){
            // return this.$route.query.redirect
            this.$router.push(this.$route.query.redirect)
        }else{
            // return '/'
            this.$router.push('/')
        }
    }
}
  • https://v2.vuejs.org/v2/guide/computed.html#Computed-Properties
  • https://v2.vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods

"However, the difference is that computed properties are cached based on their dependencies. A computed property will only re-evaluate when some of its dependencies have changed. This means as long as message has not changed, multiple access to the reversedMessage computed property will immediately return the previously computed result without having to run the function again."

methods vs computed and filters :

  • Access vue instance/data inside filter method

本文标签: javascriptVuerouter 2 changes route but does not update the viewStack Overflow