通常vue注册或登录保存用户状态需要用到Vuex和Vue Router
Vuex:保存用户状态,是否登录等
Vue Router:页面路径与权限
在一个Vue项目中,store文件夹一般是Vuex文件夹,我们可以创建一个index.js文件 最简单的 Store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state () {
return {
//sessionStorage
uid:window.sessionStorage.getItem('uid'),//storage默认存储为字符串,转换成原本数据格式
isLogin: window.sessionStorage.getItem('isLogin'),
//localstorge
autoLoginIn30Days:window.localStorage.getItem('autoLoginIn30Days'),
LocalUid:window.localStorage.getItem('LocalUid'),
localIsLogin:window.localStorage.getItem('localIsLogin'),
}
},
getters: {
},
mutations: {
//sessionStorage
$_setLogin (state, value) {
state.isLogin = value
sessionStorage.setItem('isLogin', value)
},
$_setUID(state,value){
state.uid=value
sessionStorage.setItem('uid',value)
},
// localstorge
$_setLocalLogin (state, value) {
state.localIsLogin = value
localStorage.setItem('localIsLogin', value)
},
$_setLocalUID(state,value){
state.LocalUid=value
localStorage.setItem('LocalUid',value)
},
AUTO_LOGIN:(state,value)=>{
state.autoLoginIn30Days=value
if(state.autoLoginIn30Days){
window.localStorage.setItem('LocalUid',state.LocalUid)//
window.localStorage.setItem('localIsLogin',state.localIsLogin)
window.localStorage.setItem('autoLoginIn30Days',state.autoLoginIn30Days)
}else{
window.localStorage.removeItem('localIsLogin')
window.localStorage.removeItem('LocalUid',state.LocalUid)
window.localStorage.setItem('autoLoginIn30Days',state.autoLoginIn30Days)
}
},
LOGOUT:(state)=>{
state.localIsLogin=null
state.localUser=null
state.autoLoginIn30Days=false
window.sessionStorage.removeItem('isLogin')
window.sessionStorage.removeItem('user')
window.localStorage.removeItem('localIsLogin')
window.localStorage.removeItem('localUser')
window.localStorage.setItem('autoLoginIn30Days',false)
}
}
})
export default store
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,更改store.state的方法都写在mutations: {}中,这里面我们写了几个方法:
方法1.使用sessionStorage保存当前登录uid和是否已登录isLogin
方法2.localStorage保存登录uid和是否已登录isLogin
我们看b站的登录注册有实现记住我免登陆的功能,要实现类似的效果是:
如果用户未勾选记住我,则只使用方法1 sessionStorage保存用户信息,如果用户勾选了记住我,则要使用方法2 localStorage保存用户信息
这里AUTO_LOGIN方法就是30天免登陆的状态提交到store,LOGOUT是退出登录提交到store
实现判断页面是否需要登录
项目中有一些路由是需要登录才可以进入的,比如个人中心等
有一些路由是不需要登录就可以进入,比如登录页等
去到routes.js文件更改:
{
path: '/',
redirect: '/home',// 域名直接跳转到主页
},
{
//登录
path: '/login',
component: login,
meta: {
isLogin: false
}
},
{
//个人中心
path: '/personal',
component: personal,
meta: {
isLogin: true
}
},
定义路由的时候可以配置 meta 字段:个人中心页 meta: { isLogin: true } ,参考官网可知,在全局导航守卫中检查元字段,这个全局导航就是我们权限判断的重点,通常写在router文件夹中,我们为了展示直接写在项目\src\main.js文件中
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import '@/style/index.scss'
import '@/utils/rem'
import axios from '@/utils/axios'
import store from './store/index'
import global from './utils/global'
Vue.config.productionTip = false
Vue.use(global)
router.beforeEach((to, from, next) => {
const isLogin=store.state.isLogin ? store.state.isLogin: window.sessionStorage.getItem('isLogin')
const localIsLogin=store.state.localIsLogin ? store.state.localIsLogin: window.localStorage.getItem('localIsLogin')
let AuthLogin=window.sessionStorage.isLogin=='true' || window.localStorage.getItem('autoLoginIn30Days')=='true' && window.localStorage.getItem('localIsLogin')=='true'
if (to.matched.some(m => m.meta.isLogin)) {//需要认证的页面
if (!AuthLogin) {//如果未认证
next({path: '/login',query:{}})
return
}else{
next()
}
}else{
if(AuthLogin){//如果已登录,还想想进入登录注册界面,则定向回首页
next({path: '/home',query:{}})
}else{
next()
}
}
})
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
那么判断逻辑已完成,实现的效果是,如果用户进入一个meta字段isLogin:true的页面,则表示这个页面需要认证,
if (to.matched.some(m => m.meta.isLogin)) {
...
}
使用to.matched.some就是遍历路由数组中每个值进行判断,这样做的好处是子路由to.matched则只需要给较高一级的路由添加requiresAuth即可,其下的所有子路由不必添加。官网也是这样写的:
最后只需在项目的login.vue中,登录验证方法里后提交状态到store即可
if(this.rememberMe){//勾选了记住我
this.$store.commit('$_setLocalLogin',true)
this.$store.commit('$_setLocalUID',123)
this.$store.commit('AUTO_LOGIN',true)
}else{
this.$store.commit('AUTO_LOGIN',false)
}
this.$store.commit('$_setLogin',true)
this.$store.commit('$_setUID',123)
this.$router.push({ name: 'home', params: {}})
实现了登录逻辑:保存状态30天内免登陆
在login页面登录,如果用户验证通过,使用this.$store.commit提交,用户信息保存到sessionStorage,同时用户如果勾选了记住我,提交AUTO_LOGIN,用户信息保存到了localStorage,关闭浏览器后下次,直接访问域名->跳转到home页,无需登录,用户需在右上角点击退出账号则清空localstorage
当然这里还需要后台校验接口,用户登录成功后保存令牌,这个令牌有过期时间,检测验证用户来源等,那么用户需要再次登录了