学习完Vue3+TS后 最近使用Vue3+TypeScript搭建了个新的系统,登录信息缓存到vuex、localstorage中,路由默认指向main,如果没有登录拦截到/login,如果以前登录过,再次登录,系统会判断localstorage中是否有账户密码以及token,这时候由于vuex是在内存中的,刷新页面,vuex是会没有数据的,而localstorage是有的,这会导致一些问题的发生,需要处理
- localStorage的封装
- token携带
- VueX封装
- Vue路由拦截
- 此处axios忽略封装,可以自己找个封好的axios模板。
首先登录逻辑分析
1、用户输入登录信息,正则判断是否符合规则,此处使用ElementPlus,给出正则规则校验,校验通过后点击登录按钮才发送请求
2、发送请求拿到axios的promise对象,如果账户密码正确,我们可以拿到res.data中的字段为id,name,token
因为我们需要在后续的主页中拿到用户信息,比如需要权限管理,我们就需要分清用户,我们需要将信息存到Vuex中,缓存登录状态需要将信息存入LocalStorage中,我们提前做好VueX和LocalStoage的使用
3、封装LocalStorage
常用的LS方法 set get delete clear 我们提前给他封好 ,用的时候直接调用对应的方法。
创建独立的utils
class localCache {
setCache(key: string, value: any) {
window.localStorage.setItem(key, JSON.stringify(value))
}
getCache(key: string) {
const value = window.localStorage.getItem(key)
if (value) {
return JSON.parse(value)
}
}
deleteCache(key: string) {
window.localStorage.removeItem(key)
}
clearCache() {
window.localStorage.clear()
}
}
export default new localCache()
然后将他export default导出,这里LocalStorage完成
4、封装Vuex
interface IloginModule {
token: string
userInfo: any
userMenus: any
}
const loginModule: Module<IloginModule, IRootState> = {
namespaced: true,
state() {
return {
token: '',
userInfo: {},
userMenus: []
}
},
getters: {},
mutations: {
changeToken(state, token: string) {
state.token = token
},
changeUserInfo(state, userInfo: any) {
state.userInfo = userInfo
},
changeUserLists(state, userLists: any) {
state.userMenus = userLists
}
},
IligonModule接口给定类型 其中VueX的State中存入数据,类似Vue2的data,存入token,userInfo(用户信息),userMenus(用户登录之后菜单列表)<方便做用户权限后显示的东西>.mutations这里我们要知道Vuex中唯一提交store的方法,这里我们写三个方法可以修改这三个值。
actions异步操作mutations
actions: {
async accountLoginAction({ commit }, payload: any) {
// 实现登录逻辑
// console.log('执行accountLoginAction', payload)
const loginResult = await accountLoginRequest(payload)
const { id, token } = loginResult.data
commit('changeToken', token)
localCache.setCache('token', token)
// 请求用户信息
const userInfoResult = await requsestUserInfoById(id)
const userInfo = userInfoResult.data
commit('changeUserInfo', userInfo)
localCache.setCache('userInfo', userInfo)
// 获取用户菜单列表
const userMenuLists = await requsestUserUserMenus(userInfo.role.id)
const userLists = userMenuLists.data
commit('changeUserLists', userLists)
localCache.setCache('userLists', userLists)
console.log(userLists)
router.push('/main')
},
loadLocalLogin({ commit }) {
const token = localCache.getCache('token')
if (token) {
commit('changeToken', token)
}
const userInfo = localCache.getCache('userInfo')
if (token) {
commit('changeUserInfo', userInfo)
}
const userLists = localCache.getCache('userLists')
if (token) {
commit('changeUserLists', userLists)
}
}
}
async await包一下异步请求,accountLoginAction是登录逻辑,存入信息到Vuex中和LocalStorage中,然后跳转到main主页
loadLocalLogin 在下一步解释
Router配置
import { createRouter, createWebHashHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
import localCache from '../utils/cache'
const routes: RouteRecordRaw[] = [
{
path: '/',
redirect: '/main'
},
{
path: '/login',
component: () => import('@/views/Login/Login.vue')
},
{
path: '/main',
component: () => import('@/views/Main.vue')
}
]
const router = createRouter({
routes,
history: createWebHashHistory()
})
router.beforeEach((to) => {
if (to.path !== '/login') {
const token = localCache.getCache('token')
if (!token) {
return '/login'
}
}
})
export default router
History的Router配置 在BeforeEach钩子中判断要去的路由是不是登录,不是我们就获取一遍LocalStorage中的Token 如果没有token 就return到登录
这里 如果我们刷新页面,Vuex数据清空,LS中依然有数据loadLocalLogin方法判断LS中有没有三个值,如果有就赋值到Vuex中,这个方法导出出来,在Vue的Main.js中引用,这样每次进入页面都可以调用这个方法,这样Vuex的状态就会一直存在,解决了整个登录流程
<感谢Coderwhy大神,前端引路人>