通过接收后台返回数据来实现Vue动态路由
动态路由加载
·
应用场景
用户登录成功后,通过后台接口返回该用户可访问的路由
router配置
src/router/index.js文件
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
// 解决Vue-Router升级导致的Uncaught(in promise) navigation guard问题
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location, onResolve, onReject) {
if (onResolve || onReject)
return originalPush.call(this, location, onResolve, onReject);
return originalPush.call(this, location).catch((err) => err);
};
// 公共路由
const constantRoutes = [
{
path: '/login',
name: 'login',
component: () => import('@/views/login/index'),
meta: {
title: '登录',
},
hidden: true
},
{
path: '/404',
component: () => import('@/views/error/404'),
meta: {
title: '404',
},
hidden: true
},
];
// 清空路由表
export const asyncRouterMap = [];
const createRouter = () =>
new VueRouter({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes,
});
const router = createRouter();
// 重置路由,放置重复添加崩溃
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
权限配置
src/permission.js文件,在入口文件中引入
import router from './router';
import store from './store';
import { getToken } from '@/utils/auth';
import Layout from '@/views/main/index'
import menuData from '@/mock/menuData.json';
// 给后台接口数据整形
const arr = menuData.data;
let listL1 = [], listL2 = [];
for (let index = 0; index < arr.length; index++) {
if(arr[index].level === 1) {
listL1.push(arr[index])
} else if(arr[index].level === 2){
const str = arr[index].url;
arr[index].path = str.slice(str.indexOf('/'),str.indexOf('.'));
listL2.push(arr[index])
}
}
for (let i = 0; i < listL1.length; i++) {
listL1[i].children = listL2.filter(item=>item.parentId === listL1[i].id)
}
const whiteList = ['/login']; // 没有重定向白名单
router.beforeEach(async (to, from, next) => {
// 设置页面标题
if(to.name){
document.title = to.name //修改网页的title
}
// 判断用户是否已经登录
const hasToken = getToken();
// debugger
if (hasToken) {
if (to.path === '/login') {
// 如果已经登录,则重定向到主页
next({ path: '/index' });
} else {
const hasGetUserRouter = store.state.dynamicRoutes; // 是否有路由表
if (hasGetUserRouter.length > 0) {
// const button = to.meta.button
// store.commit('permission/SET_BUTTON', button) // 设置当前页面按钮权限
next();
} else {
try {
store.dispatch('dynamicRoutes', listL1)
routerGo(to, next, listL1);
} catch (error) {
store.dispatch('token')
next(`/login`);
}
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next();
} else {
next(`/login`);
}
}
});
router.afterEach(() => {
// finish progress bar 进度条
// NProgress.done()
});
// 根页面
const menuRoot = {
path: '/',
component: Layout,
redirect: '/index',
name: '主页面',
meta: { title: '主页面', icon: 'el-icon-s-help' },
children: [],
}
// 导航到一个新的路由方法封装
function routerGo(to, next, routerList) {
const newRouter = filterAsyncRouter(routerList); // 过滤路由
const menuRouterTemp = { ...menuRoot };
menuRouterTemp.children = newRouter
router.options.routes.push(menuRouterTemp);
router.addRoute(menuRouterTemp);
router.addRoute({ path: '*', redirect: '/404', hidden: true });
next({ ...to, replace: true });
}
// 过滤路由方法封装-拼接路径
function filterAsyncRouter(asyncRouterMap,res) {
res = res || [];
asyncRouterMap.forEach((elem) => {
if (!elem.children) {
let obj = { ...elem };
obj.component = (resolve) =>
require([`@/views${elem.path}`], resolve);
res.push(obj);
} else {
filterAsyncRouter(elem.children, res);
}
});
return res;
}
展示效果
更多推荐
已为社区贡献6条内容
所有评论(0)