Reputation: 861
I have a login issue with website that uses:
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
Upvotes: 18
Views: 18935
Reputation: 509
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('/')
}
}
}
"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 :
Upvotes: 0
Reputation: 6760
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>
Upvotes: 12
Reputation: 31
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!
Upvotes: 1
Reputation: 21
Vue re-uses components where possible. You should use beforeRouteUpdate
to react to a route switch that uses the same component.
Upvotes: 2