后台管理系统
一、菜单权限业务
超级管理员的页面:首页、权限模块、商品模块
初级管理员:首页
不同的用户、不同角色的任务,项目当中所能操作的、看见的菜单是不一样的。
如何实现菜单的权限?不同的用户所能操作|查看菜单不一样的?
-
起始不同的用户(角色),登录的时候会向服务器发请求,服务器会把用户相应的菜单的权限的信息,返回给我们
-
我们可以根据服务器返回的数据(信息),可以动态的设置路由,可以根据不同的用户展示不同的菜单。
菜单权限:当用户获取用户信息的时候,服务器会把相应的用户拥有菜单的权限信息返回,需要根据用户身份对比出,当前这个用户需要展示哪些菜单
1.路由模块划分
- 路由的配置:为什么不同用户登录我们的项目,菜单(路由)都是一样的?
因为咱们的路由‘死的’,不管你是谁,你能看见的,操作的菜单都是一样的,需要把项目中的路由进行拆分
常量路由:所有用户都可以跳转的路由
// 常量路由:所有用户都可以看到的路由
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard' }
}]
},
异步路由:有的用户没有权限跳转的路由
// 异步路由:不同用户需要过滤的路由
export const asyncRoutes = [
//管理权限
{
name: 'Acl',
path: '/acl',
component: Layout,
redirect: '/acl/user/list',
meta: {
title: '权限管理',
icon: 'el-icon-lock'
},
children: [
{
name: 'User',
path: 'user/list',
component: () => import('@/views/acl/user/list'),
meta: {
title: '用户管理',
},
},
{
name: 'Role',
path: 'role/list',
component: () => import('@/views/acl/role/list'),
meta: {
title: '角色管理',
},
},
{
name: 'RoleAuth',
path: 'role/auth/:id',
component: () => import('@/views/acl/role/roleAuth'),
meta: {
activeMenu: '/acl/role/list',
title: '角色授权',
},
hidden: true,
},
{
name: 'Permission',
path: 'permission/list',
component: () => import('@/views/acl/permission/list'),
meta: {
title: '菜单管理',
},
},
]
},
// 商品管理
{
path: '/product',
component: Layout,
name: 'Product',
meta: { title: '商品管理', icon: 'el-icon-goods' },
children: [
{
path: 'trademark',
name: 'TradeMark',
component: () => import('@/views/product/tradeMark'),
meta: { title: '品牌管理' }
},
{
path: 'attr',
name: 'Attr',
component: () => import('@/views/product/Attr'),
meta: { title: '平台属性管理' }
},
{
path: 'spu',
name: 'Spu',
component: () => import('@/views/product/Spu'),
meta: { title: 'Spu管理' }
},
{
path: 'sku',
name: 'Sku',
component: () => import('@/views/product/Sku'),
meta: { title: 'Sku管理' }
},
]
},
];
2.vuex仓库模块开发(数据对比与合并)
将服务器返回的数据中的路由信息与异步路由进行对比出当前用户到底显示哪些异步路由
获得服务器返回的数据
const actions = {
//获取用户信息
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
//获取用户信息:返回数据包含:用户名name、用户头像avatar、routes[返回的标志:不同的用户应该展示哪些菜单的标记]、roles(用户角色信息)、buttons【按钮的信息:按钮权限用的标记】
const { data } = response;
//vuex存储用户全部的信息
commit('SET_USERINFO',data);
commit('SET_RESULTASYNCROUTES',computedAsyncRoutes(cloneDeep(asyncRoutes),data.routes));
resolve(data)
}).catch(error => {
reject(error)
})
})
},
对比数据
//定义一个函数:两个数组进行对比,对比出当前用户到底显示哪些异步路由
const computedAsyncRoutes = (asyncRoutes,routes)=>{
//过滤出当前用户【超级管理|普通员工】需要展示的异步路由
return asyncRoutes.filter(item=>{
//数组当中没有这个元素返回索引值-1,如果有这个元素返回的索引值一定不是-1
if(routes.indexOf(item.name)!=-1){
//递归:别忘记还有2、3、4、5、6级路由
if(item.children&&item.children.length){
item.children = computedAsyncRoutes(item.children,routes);
}
return true;
}
})
}
数据的合并
const mutations = {
//最终计算出的异步路由
SET_RESULTASYNCROUTES:(state,asyncRoutes)=>{
//vuex保存当前用户的异步路由,注意,一个用户需要展示完成路由:常量、异步、任意路由
state.resultAsyncRoutes = asyncRoutes;
//计算出当前用户需要展示所有路由
state.resultAllRputes = constantRoutes.concat(state.resultAsyncRoutes,anyRoutes);
//给路由器添加新的路由
router.addRoutes(state.resultAllRputes)
}
}
运用到数组的filter、indexOf、concat方法
3.页面的渲染
文件位置
html代码
```javascript
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
计算数据
computed: {
routes() {
return this.$store.state.user.resultAllRputes;
},
}