欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue-element-admin登录流程梳理

程序员文章站 2022-05-19 17:08:14
...

一、准备工作

项目模板采用vue-element-admin,使用vue和element-ui实现

1.目录结构

vue-element-admin登录流程梳理

permission.js

登录流程中,permission.js是最重要的环节,这个文件是路由的全局钩子(beforeEach和afterEach),全局钩子的意思就是每次跳转的时候可以根据情况进行拦截,不让他跳转。使用场景就是有些页面需要登录才能访问,这时候就可以在beforeEach中校验用户登录状态来进行拦截。

utils/auth.js

设置token到cookie中的操作封装。

router

有关路由的一些设置

二、登录流程解析

登录页面:view/login/index.vue

vue-element-admin登录流程梳理
点击登录按钮后,触发handleLogin方法,利用validate进行表单验证,如果验证通过,调用user/login方法传递表单里的数据,根据.then回调执行this.$router.push方法,这个方法用于跟踪:我是从哪里跳到/login页面的,登录后我就返回哪里。

/user/login方法:src/store/modules/user.js

vue-element-admin登录流程梳理
这个方法主要做了以下工作:登录验证,登录成功后,分别把token保存在vuex和cookie中。

permission.js :src/permission.js

router.beforeEach(async(to, from, next) => {
  // 从cookie中取得token
  const hasToken = getToken()
  
  // 如果有token 也就是已经登陆的情况下
  if (hasToken) {
    // 并且要前往的路径是'/login'  则返回 '/' 
    if (to.path === '/login') {
      next({ path: '/' })
    } else {
      // 从store中取得用户的 roles, 也就是用户的权限 并且用户的权限数组必须有一个以上
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      // 有权限则直接进入
      if (hasRoles) {
        next()
      } else {
        // 没有权限的话
        try {
          // 获取用户信息
          const { roles } = await store.dispatch('user/getInfo')
          // 生成可访问路由
          const accessRoutes = await store.dispatch('permission/generateRoutes',                                    roles)
          // 将可访问路由添加到路由上
          router.addRoutes(accessRoutes)
          // 进入路由
          next({ ...to, replace: true })
        } catch (error) {
          // 如果出现异常  清空路由 
          await store.dispatch('user/resetToken')
          // Message提示错误
          Message.error(error || 'Has Error')
          // 跳到login页面重新登陆
          next(`/login?redirect=${to.path}`)
        }
      }
    }
  } else {
    // 没有token 也就是没有登陆的情况下  
    // 判断是否是白名单(也就是说不需要登陆就可以访问的路由)
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      // 其他的一律给我跳到login页面 老老实实的进行登陆
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

利用beforeEach进行访问拦截,如果没登录,跳转到登录页面进行登录。

user/getInfo:src/store/modules/user.js

vue-element-admin登录流程梳理
getInfo用于获取用户信息并保存到vuex中,后面是一堆的数据校验。

permission/generateRoutes:src/store/modules/permission.js

// 判断是否有权限
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    // roles.some => Array.some 相当于是只要有一个满足就为true 
      
    // 判断用户的权限于当前路由访问所需要的权限是否有一个满足
    // 比如说用户权限为 ['one','two']  当前路由访问所需要权限为 ['two','three']  那么就说明当前用户可以访问这个路由
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    // 默认是可访问的
    return true
  }
}
// 生成可访问路由
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    // 判断当前路由是否可以访问
    if (hasPermission(roles, tmp)) {
      // 如果当前路由还有子路由
      if (tmp.children) {
        // 进行递归处理
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      // 将可访问路由放入数组中
      res.push(tmp)
    }
  })  
  // 返回
  return res
}
// 为什么要写这里呢,因为后面的Sidebar组件与这个环环相扣
const mutations = {
  SET_ROUTES: (state, routes) => {
    // 添加的路由
    state.addRoutes = routes
    // 将vuex中的路由进行更新
    state.routes = constantRoutes.concat(routes)
  }
}
const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      // 如果roles包含 'admin' 直接可以全部访问
      if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        // 利用 filterAsyncRoutes 过滤出可访问的路由
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      // 保存可访问的路由到store中
      commit('SET_ROUTES', accessedRoutes)
      // 将可访问路由返回
      resolve(accessedRoutes)
    })
  }
}

generateRoutes就是根据得到的用户权限生成可以访问的路由。

动态路由实现

router.addRoutes(accessRoutes)

动态路由的核心代码就这一句话,短小精悍,其他的都是为了完成动态路由做的一些 “准备工作” ,user/getInfo获取用户信息得到用户的roles权限数组,返回user/generateRoutes生成可访问路由,就是这么神奇的一步,实现了动态路由。

三、总结

1 Login/index.vue点击登陆 提交user/login的actions。
2 user/login进行登陆验证,登陆成功之后保存token到vuex和cookie中。
3 回到Login/index.vue跳转路由,这时就到了permission.js
4 permission.js进行判断是否登陆,是否有用户信息?没有用户信息就获取用户信息,并且保存到vuex,然后根据用户信息中的roles生成可访问路由,并通过addRoutes进行添加。

登录流程图

vue-element-admin登录流程梳理

相关标签: Vue vue