后台管理系统中的一些理解

527 阅读2分钟

前言

allen-admin-template 项目 github 地址

从实习开始一直认为后台管理系统没什么含量,开发不就有手就行,直到这段时间才发现并不是那么回事。

自己仿了一个基于 vue-admin-template 的后台系统模板。( allen-admin-template 嘿嘿,很不要脸,用了自己的名字)主要是为了深入的学习理解。

下文主要是一些自己的理解,和觉得一些有意思的模块。项目还在不断的跟进,此文当然也会的。

allen-admin-template 搭建

在搭建这个项目的时候,就觉得已经不太简单了,需要考虑的点还是挺多的。

  • 需不需要用vuex, ts, sass 等等。
  • 团队开发的话需要有哪些风格约束,我最后还是选择了 ESLint + Prettier
  • 数据方面的处理是用 easy-mock。
  • 封装 axios
  • 开发环境和正式环境区分。如:在项目根目录创建 .env.development,声明一个变量指定 开发环境 axios 中的 baseURL。 正式环境 创建 .env.production

登录模块 && 动态路由

登录到获取路由流程

将 username, password 传到后端,后端返回一个token,然后再用这个token 调取一个获取用户信息(roles、name、avatar等),这里主要讲roles。这个项目是前端写好的动态路由配置表,根据获取的roles和动态路由表匹配,然后得到的路由再由 router.addRoute() 加入。

把这两个模块分开来讲一讲。

登录模块

username, password 传到后端来获取token,前端将获取的 token 保存到 cookie 中。 token 再调用获取用户信息的接口,将返回的数据保存到vuex中。今后每一次路由跳转的时候,都要判断有没有 token ; axios 请求拦截器自定义头部字段携带token,传到后端且其判断有没有过期。若出现了其中一种情况则会需要重新登录,则携带着当前 url 中origin 之后的路径,作为路由参数回到登陆页面。这主要是为了页面重定向,回到重新登陆之前的页面。

如:

token异常前的url: http://localhost:9528/#/dashboard 
重新登录的url:  http://localhost:9528/#/login?redirect=%2Fdashboard

// 主要通过
router.beforeEach(async (to, from, next) => {
    ...
    next(`/login?redirect=${to.path}`)
    ...
})

动态路由

这个项目的动态路由主要是前端写好动态路由的配置表。

const asyncRoutes = [
  {
    path: '/permission',
    component: Layout,
    meta: {
      roles: ['admin', 'editor'], // you can set roles in root nav
    },
    children: [
      {
        path: 'page',
        component: () => import('@/views/permission/page'),
        meta: {
          title: 'Page Permission',
          roles: ['admin'], // or you can only set roles in sub nav
        },
      },
    ]
  }

根据 token 获取个人信息中的 roles,根据这个 roles 去和动态路由的 meta 里的 roles 匹配(具体实现在vuex 的 permission 模块体现),匹配得到的路由通过 router.addRoute 加入。基本路由和 router.addRoute 加入的路由 就形成了该用户的一个完整路由。

前端自动化模块

目前该项目体现自动化的地方,只有模块引入的地方。我还会不断学习且完善。 之前是在电商公司实习的,后台系统就有一堆模块,每个模块中又有很多路由,则这些模块都会独立一个文件来写,这时候就会需要在 index.js 文件中引入这些模块。每次创建一个模块,都需要在 index.js 中引入一次。这里的自动化就可以让开发者,只管创建模块就可以,不需要自己引入,且 index.js 的代码可以看起来简洁一些(当模块越来越多的时候,就可以体现出来了)。

image.png

// index.js
// 自动化引入
const modules = {}
function importAll(r) {
    r.keys().forEach((modulePath) => {
        const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
        modules[moduleName] = r(modulePath).default
    })
}
importAll(require.context('./modules', true, /\.js$/))

// 替代之前的引入
//import permission from './modules/permission'
//import user from './modules/user'

webpack文档中require.context

require.context返回函数的属性具体用法

结尾

项目还在更新.....