在开发后台管理项目时,多用户多角色不同权限的场景可以说是非常普遍的。从零开始手写一个后台,要考虑的东西很多,这里直接拿网上大家比较熟悉的vue-admin-template后台模版来进行改造。
先来看下vue-admin-template这个模版的代码目录结构
├── build # 构建相关 ├── mock # 项目mock 模拟数据 ├── public # 静态资源 │ │── favicon.ico # favicon图标 │ └── index.html # html模板 ├── src # 源代码 │ ├── api # 所有请求 │ ├── assets # 主题 字体等静态资源 │ ├── components # 全局公用组件 │ ├── icons # 项目所有 svg icons │ ├── layout # 全局 layout │ ├── router # 路由 │ ├── store # 全局 store管理 │ ├── styles # 全局样式 │ ├── utils # 全局公用方法 │ ├── views # views 所有页面 │ ├── App.vue # 入口页面 │ ├── main.js # 入口文件 加载组件 初始化等 │ └── permission.js # 权限管理 ├── tests # 测试 ├── .env.xxx # 环境变量配置 ├── .eslintrc.js # eslint 配置项 ├── .babelrc # babel-loader 配置 ├── .travis.yml # 自动化CI配置 ├── vue.config.js # vue-cli 配置 ├── postcss.config.js # postcss 配置 └── package.json # package.json
login.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png
比如我们用财务这个用户去登录一下后台,(先给财务这个角色分配一下权限)

image.png
比如给他分配
培训认证全部的权限

image.png
然后管理员登录后台,只渲染所拥有的权限动态渲染了侧边栏。

image.png
补充一下:这里是按钮权限的设置,全局配置一个指令,到时候
v-permission='['add']'
就可以实现按钮是否显示。

image.png
基本上就是这么个东西,先添加菜单
,在新建一个角色
,再给这个角色分配一下权限
,然后在新建个用户
,账号密码配置一下,再给这个用户分配一个角色
,最后这个用户登录后台,就展示所拥有的权限
,动态去渲染侧边栏
第二步 : 我们先来启动一下vue-admin-template这个模版,安装依赖 cnpm install
启动:npm run dev

image.png

image.png
可以看到,全是英文的,我是受不了,(英文烂的一逼,看不懂),侧边栏是手写的英文,删掉就好了,element-ui 是英文的,这个要改一下配置。
修改路径 src/main.js // Vue.use(ElementUI, { locale }) // 如果想要中文版 element-ui,按如下方式声明 Vue.use(ElementUI) 😄
当然要先实现正常登录,我这里用下真实的登录接口,修改一下src/api/user.js

image.png
.env.development

image.png
vue.config.js
配置反向代理,然后重启项目

image.png
箭头标注的根据实际情况修改

image.png
这样实际是触发登录接口了,为啥没登录进去呢,因为登录成功后,会立即触发getinfo 这个接口,这个接口请求出错,就会清除token且又回到登录页了。
所以接下来要完善getinfo这个接口,先来看下逻辑
1.执行完登录请求后,会走 permission.js
中的逻辑

image.png
可以看到getinfo,所以就要完善getinfo这个接口,同样换成真实的。

image.png
store/modules/user.js
根据实际情况修改下getinfo这个方法,这里看自己公司要求,我们只是取到昵称和头像存起来,也可以在这个方法直接把该用户所拥有的权限拿到并保存到vuex,建议在起一个接口,模拟的话我先在这个方法里把路由信息写死,然后在定一个存储到vuex的方法
const getDefaultState = () => { return { token: getToken(), name: '', avatar: '', menus: "",//新增 } } const mutations = { RESET_STATE: (state) => { Object.assign(state, getDefaultState()) }, SET_TOKEN: (state, token) => { state.token = token }, SET_NAME: (state, name) => { state.name = name }, SET_AVATAR: (state, avatar) => { state.avatar = avatar }, // 新增 SET_MENUS: (state, menus) => { state.menus = menus } } // get user info getInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo().then(response => { //用户信息是根据token返回的, //我们把token放到header里自动带过去了,这里就把state.token删掉了 const { data } = response if (!data) { return reject('Verification failed, please Login again.') } const { nickname, avatar } = data // 模拟请求数据 const menus = [ { "path": "/system", "redirect": "/menu", "component": "Layout", "meta": { "title": "系统管理", "icon": "form" }, "children": [{ "path": "/menu", "name": "menu", "component": "menu/index", "meta": { "title": "菜单管理", "icon": "table", } }, { "path": "/roles", "name": "roles", "component": "roles/index", "meta": { "title": "角色管理", "icon": "table", } }, { "path": "/administrator", "name": "administrator", "component": "dashboard/index",