vue-elementui-admin 动态路由渲染
vue-elementui-admin 动态路由渲染在官网下载vue-elementui-admin,进行二次开发,实现动态路由渲染,用户登录后,通过接口从服务端获取权限列表,然后渲染到侧边栏。注意:此次二次开发未涉及角色(role)删选,需要角色删选权限的可以绕行1、router.js(@/router/router.js)定义constantRouterMap:放置所有权限都需要的路由表,例如
vue-elementui-admin 动态路由渲染
在官网下载vue-elementui-admin,进行二次开发,实现动态路由渲染,用户登录后,通过接口从服务端获取权限列表,然后渲染到侧边栏。
注意:此次二次开发未涉及角色(role)删选,需要角色删选权限的可以绕行
1、router.js(@/router/router.js)
定义constantRouterMap:放置所有权限都需要的路由表,例如登录页等。
// router.js
import Router from 'vue-router';
import Layout from '@/layout'
import Login from '../views/login/';
//如首页和登录页和一些不用权限的公用页面
export const constantRouterMap = [
{ path: '/login', component: Login },
{
path: '/',
component: Layout,
redirect: '/home',
children: [{
path: 'home',
name: 'home',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页12', icon: 'dashboard' }
}]
}
]
const createRouter = () => new Router({
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})
const router = createRouter()
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
2、permission.js(@/store/modules/permission.js)
2.1 创建文件:@/store/modules/permission.js
用于动态获取权限菜单,
2.2 将constantRouterMap
加载到js中备用,将值存入vuex中管理,所以需要在index.js
中注册一下:
import permission from './modules/permission'
const store = new Vuex.Store({
modules: {
.......,(此处是其他模块)
permission
},
getters
})
2.3 将需要用到的值存储到vuex中,在getting.js
中配置
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
// 添加值
addRouters: state => state.permission.addRouters,
routers: state => state.permission.routers
}
export default getters
2.4 获取接口进行路由动态拼接
经测试,component不可以动态获取组件,所以可以事先将组件加载到一个map对象中,然后路由动态生成的时候直接获取对象属性值即可(也可以自己做尝试,我写的一直报错,大神可留言赐教┭┮﹏┭┮…),注意讲404页也添加到路由中。
import { constantRouterMap } from '@/router/router.js';
import Layout from '@/layout'
//获取后台路由的接口
import { getMenuList } from '@/api/router';
//提前加载组件
const map = {
userList: () => import('@/views/user/userList'),
nodeList: () => import('@/views/node/nodeList')
}
const state = {
routers: constantRouterMap,
addRouters: []
};
const mutations = {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers;
state.routers = constantRouterMap.concat(routers);
}
};
let asyncRouterMap = [];
const actions = {
GenerateRoutes({ commit, state }) {
return new Promise(resolve => {
if (state.addRouters && state.addRouters.length > 0) {
resolve();
} else {
getMenuList().then(res => {
for (let i = 0; i < res.data.length; i++) {
let item = res.data[i];
let router = {
path: `/${item.path}`,
name: `${item.path}`,
component: Layout,
alwaysShow: true,
meta: { title: `${item.name}`, icon: `${item.icon}` },
children: []
}
if (item.children && item.children.length > 0) {
for (let j = 0; j < item.children.length; j++) {
let childItem = item.children[j];
let child = {
path: `${childItem.path}`,
name: `${childItem.path}`,
component: map[childItem.path],
meta: { title: `${childItem.name}`, icon: 'dashboard' }
}
router.children.push(child);
}
}
asyncRouterMap.push(router);
}
let router404 = { path: '*', redirect: '/404', hidden: true };
asyncRouterMap.push(router404);
console.log(asyncRouterMap, "asyncRouterMap");
commit('SET_ROUTERS', asyncRouterMap);
resolve();
});
}
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
3、permission.js
注意:在同级的main.js入口文件中使用。
与App.vue
与main.js
同级,创建文件permission.js
,通过钩子函数router.beforeEach
对路由进行加工,即在router.js
定义的constantRouterMap
的基础上,通过router.addRoutes
添加我们获取的数据.
注意:此处的问题,如果我们不加限制直接添加动态获取的路由,会重复添加,所以要限制只加载一次,因为路由是后续生成的,当我们刷新的时候,vuex中还没有动态路由,所以会出现404的情况,所以我们定义一个函数reSetPermissionList
,如果我们访问的路由不是login并且此刻我们的addRouters
为空,则去加载调用permission/GenerateRoutes
,去添加addRouters
,完成操作以后,将vuex中的addRouter
通过router.addRoutes
添加到最终渲染路由。
3.1 reSetPermissionList 防止重复加载,以及防止404的函数
const reSetPermissionList = to => {
return new Promise((resolve, reject) => {
console.log(store.getters.addRouters,"12345");
if (to.path !== '/login' && store.getters.addRouters.length === 0) {
store.dispatch('permission/GenerateRoutes').then(() => {
router.addRoutes(store.getters.addRouters);
resolve('permCode')
}).catch(error => {
resolve('permCode')
})
} else {
resolve()
}
})
}
2、钩子函数router.beforeEach
router.beforeEach((to, from, next) => {
NProgress.start()
document.title = getPageTitle(to.meta.title)
//判断是否登录
const hasToken = getToken()
if (hasToken) {
//如果登录状态下还访问login,则直接定到/
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
} else {
//登录状态下,访问to.path,调用reSetPermissionList方法
reSetPermissionList(to).then(data => {
console.log(data, "data========");
data === 'permCode' ? next({ path: to.path,加载方法,, query: to.query }) : next()
})
}
} else {
//未登录情况下,判断是否是白名单
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
})
router.afterEach(() => {
NProgress.done()
})
4、接口数据
更多推荐
所有评论(0)