当前位置: 首页 > news >正文

老板让我十分钟上手nx-admin

大体流程

参考资料:

nx-admin项目地址

首先这里就不讲解vue和vuex之类的基础东西了 有兴趣的可以去官方文档了解。这里根据流程走向大概说说

路由配置

首先找到路由配置,路由配置放在了src/router/index.js路由配置里暴露了两个常量 一个是 constantRouterMap 另外一个是 asyncRouterMap 这里先说说constantRouterMap。 nx-admin的权限验证大概是

  • 1 默认大家都能访问的页面,不需要权限, 都访问的页面定义为 constantRouterMap
  • 2 需要登录或者需要权限的页面路由定义为 asyncRouterMap

根据后台获取到用户信息role(权限)的不同来动态加载asyncRouterMap中meta.role的权限对应的页面

登录成功后做的事情

点击登录以后 左侧的侧边栏有导航列表。 这里提出两个疑问?

  • 根据路由配置说的 动态加载对应的权限路由 那么侧边栏那么多路由 肯定不能写死吧?
  • 我点击登录后 那些登录流程怎么走的?用户权限存在哪里?token在哪里?

侧边栏的动态渲染

根据问题1来回答 首先我们找到layout也就是src/views/layout/Layout.vue
因为在路由配置文件我们看见asyncRouterMap中好多组件的父组件都是LayoutLayout中我们就可以看到有个组件sidebar
ok继续找sidebar这个组件 src/views/layout/components/Sidebar/index.vue,发现这里就是渲染侧边栏的,然后找到渲染的变量是permission_routers 这个变量是存在vuex里面的,也就是说路由是存在vuex的 所以咋们去vuex里面找找看 src/store/modules/permission.js

路由的动态加载

src/store/modules/permission.js 这个文件里面有个actions

 GenerateRoutes({ commit }, data) {
      return new Promise(resolve => {
        const { roles } = data
        let accessedRouters
        if (roles.indexOf('admin') >= 0) {
          accessedRouters = asyncRouterMap
        } else {
          accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
        }
        commit('SET_ROUTERS', accessedRouters)
        resolve()
      })
    }

发现就是这一段代码更改了permission_routers,具体逻辑咱们不看 简单解释来说就是

 如果用户的权限是管理员
        把asyncRouterMap所有的路由页面都渲染出来,毕竟管理员嘛 你懂的权限嘛。
    否则 
        我不是管理员但是也不是游客就是一小市民 那么我要去asyncRouterMap中找找我小市民能够访问哪些页面。

看完这段逻辑咋们就知道了这个路由是如何动态更改的了,等等,是不是忘了啥? 虽然我知道这个actions,但是。。。在哪调用的? 经过深思熟虑的着想,在花了0.1s后 就得出,既然是路由嘛 肯定是有个全局的地方要做判断的 所以得出结论就是 router.beforeEach, 一开始去找那个啥src/main.js,发现beforeEach被分离在src/permission.js 打开这个文件。一切疑问都解开了。

用户权限的获取

说真的。。这个文件好长。。都不想看了。。。。 下图的代码这么长 看个毛啊。。于是我简单翻译了下

router.beforeEach((to, from, next) => {
  NProgress.start() // start progress bar 
  if (getToken()) { // 判断是否有token
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done() // router在hash模式下 手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行!
    } else {
      if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
        store.dispatch('GetUserInfo').then(res => { // 拉取user_info
          const roles = res.data.role
          store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可访问的路由表
            router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
            next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
          })
        }).catch(() => {
          store.dispatch('FedLogOut').then(() => {
            Message.error('Verification failed, please login again')
            next({ path: '/login' })
          })
        })
      } else {
        // 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
        if (hasPermission(store.getters.roles, to.meta.role)) {
          next()//
        } else {
          next({ path: '/401', query: { noGoBack: true }})
          NProgress.done() // router在hash模式下 手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行!
        }
        // 可删 ↑
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
      next()
    } else {
      next('/login') // 否则全部重定向到登录页
      NProgress.done() // router在hash模式下 手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行!
    }
  }
})

请说人话,翻译成人话的版本。。。

  每次更改页面路由
        你有没有token啊?
            有啊
                好的,你的权限是默认的权限0么?
                    是的。。我就是一游客
                        系统获取我的信息..拿到权限值,动态加载路由(GenerateRoutes)...通行...
                    不是。。我是权限汪(admin)
                        等等..我看看作者有没有把你降级
                            没有
                                好了。。你还是权限汪 请进
                            有
                                滚吧,你已经不是权限汪了,作者已经把你写成战斗力只有5的渣渣了
            没有
                没有还敢闯这里?滚去关口(/login)

没错,就这么简单。整个权限验证流程就完整了。剩下的就是读读文档啊,看看如何使用组件之类的了。

参考 https://github.com/Relsoul

相关文章:

  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • Flutter Android端启动白屏
  • 九、一级缓存、二级缓存
  • zabbix监控
  • centos7 go ENV 部署
  • swift leetcode-29 Divide Two Integers
  • 后端程序员必备的Linux基础知识
  • Linux服务器后台运行jar包
  • 统计学习方法概论(综合数据挖掘概论)
  • Postfix+dovecot邮件
  • App Icon Gear App 图标制作工具
  • 前端容灾
  • 学习 服务器部署 hello world
  • Java 基础 之 位运算
  • java泛型使用
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 0x05 Python数据分析,Anaconda八斩刀
  • Apache Pulsar 2.1 重磅发布
  • CentOS7 安装JDK
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • HomeBrew常规使用教程
  • JavaScript标准库系列——Math对象和Date对象(二)
  • laravel with 查询列表限制条数
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Yii源码解读-服务定位器(Service Locator)
  • 代理模式
  • 分类模型——Logistics Regression
  • 记录:CentOS7.2配置LNMP环境记录
  • 前端学习笔记之观察者模式
  • k8s使用glusterfs实现动态持久化存储
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • #etcd#安装时出错
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • #微信小程序:微信小程序常见的配置传旨
  • $.ajax()参数及用法
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (九)One-Wire总线-DS18B20
  • (七)c52学习之旅-中断
  • (未解决)macOS matplotlib 中文是方框
  • (一)认识微服务
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • .NET 4.0中的泛型协变和反变
  • .net core 控制台应用程序读取配置文件app.config
  • .NET DataGridView数据绑定说明
  • .NET 使用配置文件
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .net反编译工具
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • []使用 Tortoise SVN 创建 Externals 外部引用目录