Vue单页面应用登录状态判断

单页面应用相对于传统网站开发,路由地址的变化并没有请求新的页面,判断用户是否登录用传统的方式已经不能适用。

技术分析

  • 路由跳转时判断是否登录

  • 登录状态保存在全局状态

  • 如果页面是登录页不做判断

  • 如果没有登录跳转到登录页面,同时保留页面路径

  • 登录后自动跳回登录前的页面

具体实现

登录组件

当用户在登录页面成功登录以后,修改全局变量store.state.loggedtrue,为了在关闭页面后继续保留登录状态,将登录状态写入cookie(此处不安全,可让后台写入session),最后跳转至登录前的页面。

handleSubmit() {
let redirect = this.$route.query.redirect
if(<登陆成功>) {
this.$refs.loginForm.resetFields()
//修改全局登录状态变量为已登录,并且将登录状态写入cookie
this.$store.commit('changeLoggedState', true)
//跳转至之前的页面
if(redirect !=='/login' && redirect !=='' && !!redirect) {
this.$router.push(redirect)
} else {
this.$router.push({path:'/'})
}
}
}

钩子函数

router.beforeEach((route, redirect, next) => {
//如果没有登录,跳转至登录页面
if(route.path !== '/login' && !store.state.logged) {
next({path: '/login', query: {redirect: route.fullPath}})
} else {
next();
}
});

这里要注意的是router.beforeEach()钩子函数只在路由改变时才会调用,刷新页面后路由没有改变,就不回触发该钩子函数。

解决方法如下,在根子组件的beforeCreate() 钩子函数中添加如下判断

//读取cookie中的登录状态,写入全局变量,这样可以实现刷新后保持登录
//考了到安全性,需要后端配合使用session功能验证,这里只是提供思路
let logged = Cookies.get('logged')

if(!!logged) {
this.$store.commit('changeLoggedState', logged)
}

//这里和路由钩子中的判断是一样的
if(this.$route.path !== '/login' && !this.$store.state.logged) {
this.$router.push({path: '/login', query: {redirect: this.$route.fullPath}})
}
加载评论框需要翻墙