我现在有一个 headerBar
组件,上面显示了用户名称(如果设置了昵称显示昵称,否则显示用户名称),当用户点击登录按钮时,调用api
获取用户信息,保存到Vuex
的state
里面,headerBar
通过this.$store.getters.xxx
来获取用户登录信息,但是当用户刷新时,state里面的用户信息全没了,所以我考虑加入 localStorage
来保存用户信息,但是这部分代码不知道该如何“分布”,因为要考虑用户登录超时
,请小伙伴们指点指点,谢谢!
代码如下:
export default new Vuex.Store({
state: {
loginInfo: null,//当前用户简要信息
},
getters: {
GET_LOGININFO(state) {
//先从state里面获取用户登录信息
let loginInfo = state.loginInfo;
//如果 state 里面获取不到,那么从localStorage里面获取
if(!loginInfo){
loginInfo = JSON.parse(window.localStorage.getItem('loginInfo') || null)
}
return loginInfo;
},
},
mutations: {
SET_LOGININFO(state, data){
state.userInfo = data.data;
}
},
actions: {
Login(context, data) {
axios.post('/api/login', {
userName: 'admin',
pwd: '123456'
})
.then((res) => {
//登录成功,保存当前用户信息到 state 里面,以便其他组建获取
context.commit('SET_LOGININFO', res.data);
//保存到localStorage里面
window.localStorage.setItem('loginInfo', JSON.stringify(items));
return res;
})
.catch(function (error) {});
},
}
})
想请教几个问题:
1、这么使用 localStorage
正确么?或者合理么?有没有更好的方法呢?
2、在getters
下面的GET_LOGININFO
方法里面,如果进入了if(!loginInfo)
语句,该方法是否可以为 state
属性loginInfo
赋值呢(或者调用mutations
方法来给loginInfo
赋值)?
3、这样的话,如果用户点击退出
按钮,是不是意味着需要清空state的loginInfo,还需要清除localStorage下面的loginInfo呢?
4、这样的话,从客户端角度来看,是不是客户就永远保持以登录状态了?这个环节该怎么做好呢?
补充:第二个问题其实就是:getters里面的方法是否可以为state属性赋值(直接访问state属性赋值 或者 调用mutations方法赋值)?
不合理。用户登录成功以后应该在本地保存一份用户数据,注意我说的是保存到本地不是保存到
localstorage
,因为保存本地的方法有很多种,比如cookie
、indexedDB
等,所以,代码中不应该直接调用window.localStorage
,而是应该封装一个用户数据的读取类,解除代码耦合,将来要改成其他存储方式比较简单:不应该。个人认为不应该,
getters
语义上就是获取数据,但是却改变了数据,导致不纯净,可能会埋下维护上的隐患。是的。理论上应该有一个接口用来更新用户状态,比如判断用户是否需要重新登录之类的,比如
api/refresh
, 所以逻辑应该是:用户进入app,判断本地是否有用户信息。
有,调用
api/refresh
,判断是否需要重新登录。不需要(连续登录),将信息保存在
vuex
中,并进入首页,往后数据读取全部走vuex
。需要(长时间未登录),删除本地用户信息并跳转到登录流程。
没有, 跳转到登录流程(以下是登录流程)。
调用
api/login
登录。将保存到本地,并保存到
vuex
中,往后数据读取全部走vuex
。看3,具体还可以看看
jwt
,或者基于token
的api
设计相关的文章。