Vue3项目 登录实现 Vuex实战 localStorage使用 登录拦截 Token携带 保姆攻略

3,141 阅读3分钟

学习完Vue3+TS后 最近使用Vue3+TypeScript搭建了个新的系统,登录信息缓存到vuex、localstorage中,路由默认指向main,如果没有登录拦截到/login,如果以前登录过,再次登录,系统会判断localstorage中是否有账户密码以及token,这时候由于vuex是在内存中的,刷新页面,vuex是会没有数据的,而localstorage是有的,这会导致一些问题的发生,需要处理

  1. localStorage的封装
  2. token携带
  3. VueX封装
  4. Vue路由拦截
  • 此处axios忽略封装,可以自己找个封好的axios模板。

首先登录逻辑分析

1、用户输入登录信息,正则判断是否符合规则,此处使用ElementPlus,给出正则规则校验,校验通过后点击登录按钮才发送请求

image.png

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大神,前端引路人>

image.png

image.png