Vue通过Ajax获取后台路由信息

Vue后台获取路由信息

在这里插入图片描述


模拟后台返回路由JSON数据

export const menuRouterMap =[{name:'menu', path: '/home/menu',compPath:'components/Menu'}]

常量路由文件数据

constant.js

importHelloWorld from '@/components/HelloWorld' export const constantRouterMap =[{ path: '/HelloWorld', name: 'HelloWorld',}]

/router/index.js

importVue from 'vue'importRouter from 'vue-router' import{constantRouterMap} from './constant.js' Vue.use(Router)const router =newRouter({ routes: constantRouterMap }) router.beforeEach((to,from,next)=>{ console.log('to='+to.path+",from="+from.path);next();}) router.afterEach(()=>{ console.log('afterEach ... ');}) export default router 

/router/getrouter.js生成路由树状结构

importVue from 'vue'importstore from '@/store' importrouter from './index.js' importMainLayout from '@/layout/MainLayout' import{ menuRouterMap } from "@/router/menudata"//系统首页路由//生成路由对象数据,data是从后台检索菜单列表数据 function createRouter(data){//PC端功能路由,展示组件使用MainLayout let dataPc =[];for(var i=0;i<data.length;i++){ dataPc.push(data[i]);} let indexRouter =[{ path:'/', name:'home', component:MainLayout, meta:{ title:'首页'}, children:[...createRouterFromMenu(dataPc)]}]return indexRouter;}//根据后台获取的路由配置,装载路由数组 function createRouterFromMenu (data){const routers =[];for(let item of data){ let component ="";//function.json中"layouts/RouteView"缺失目录components,此处补充完整if(item.compPath && item.compPath.indexOf("layouts")>=0){ component ="components/"+item.compPath;}else{ component = item.compPath;} let componentPath;//动态加载组件,不需要import导入组件if(component !=null) componentPath = resolve =>require(['@/'+ component+'.vue'], resolve); let menu ={ path:item.path, name:item.name, redirect:item.redirect, component:componentPath, hidden:item.hidden, meta:{ title:item.name, icon:item.icon, url:item.path, componentName:item.compName }}if(item.child && item.child.length >0){ menu.children =[...createRouterFromMenu( item.child)];} routers.push(menu);}return routers } router.beforeEach((to, from, next)=>{ console.log('beforeEach from======'+from.path+',to======'+to.path);if(store.state.setrouter.functionList.length ===0){//如果尚未检索后台路由数据//检索后台路由数据 store.dispatch('GetFunctionList').then(res =>{const funcList = res;if(funcList !=null&& funcList != undefined){ let menuRoutes =[];//赋值前端路由实例变量 menuRoutes =createRouter(funcList);//将后台功能菜单授权路由与常量路由合并 store.dispatch('MergeMenuRouter',{ menuRoutes }).then(()=>{//addRoutes是vue-router定义的方法,用于添加路由信息 router.addRoutes(store.state.setrouter.addRouters)const redirect =decodeURIComponent(from.query.redirect ||to.path) console.log('to.path='+to.path+',redirect='+redirect);if(to.path === redirect){next({...to, replace:true})}else{next({ path: redirect })}})}else{next();}}).catch((e)=>{ console.log('2################################'+e);next({ path: '/user/login', query:{ redirect:to.fullPath,error:e }})})}else{next();}}) router.beforeResolve((to, from, next)=>{ console.log('beforeResolve ......................');next();}) router.afterEach(()=>{ console.log('afterEach .......................');})

引入Vuex组件

/store/index.js

importVue from 'vue'importVuex from 'vuex'importsetrouter from './setrouter' Vue.use(Vuex) export defaultnewVuex.Store({ modules:{ setrouter }, state:{}, mutations:{}, actions:{}, getters:{ setrouter: state => state.setrouter.setrouter,}})

/store/setrouter.js模拟Ajax请求动态路由数据,合并静态路由与动态路由数据

import{ constantRouterMap } from "@/router/constant"import{ menuRouterMap } from "@/router/menudata"const setrouter ={ state:{ routers: constantRouterMap, addRouters:[], functionList:[],}, mutations:{SET_NAME:(state, data)=>{ state.name = data; console.log('子模块---------------------SET_NAME2');},//将后台获取路由合并到常量路由对象SET_ROUTERS:(state, data)=>{ state.addRouters = data state.routers = constantRouterMap.concat(data)},SET_FUNCTIONLIST:(state, functionList)=>{ state.functionList = functionList },}, actions:{// 获取当前用户菜单权限GetFunctionList({ commit, state, getters, rootState, rootGetters }){returnnewPromise((resolve, reject)=>{resolve(menuRouterMap);commit({ type:'SET_FUNCTIONLIST', functionList:menuRouterMap });commit('SET_NAME','Module commit');})},//将后台功能菜单授权路由与常量路由合并MergeMenuRouter(context, routes){returnnewPromise(resolve =>{ let routelist = routes.menuRoutes; context.commit('SET_ROUTERS', routelist)resolve()})}}} export default setrouter 

路由视图文件

HkLayout.vue

import { constantRouterMap } from "@/router/constant" import { menuRouterMap } from "@/router/menudata" const setrouter = { state: { routers: constantRouterMap, addRouters: [], functionList: [], }, mutations: { SET_NAME: (state, data) => { state.name = data; console.log('子模块---------------------SET_NAME2'); }, //将后台获取路由合并到常量路由对象 SET_ROUTERS: (state, data) => { state.addRouters = data state.routers = constantRouterMap.concat(data) }, SET_FUNCTIONLIST: (state, functionList) => { state.functionList = functionList }, }, actions: { // 获取当前用户菜单权限 GetFunctionList({ commit, state, getters, rootState, rootGetters }) { return new Promise((resolve, reject) => { resolve(menuRouterMap); commit({ type:'SET_FUNCTIONLIST', functionList:menuRouterMap }); commit('SET_NAME','Module commit'); }) }, //将后台功能菜单授权路由与常量路由合并 MergeMenuRouter(context, routes) { return new Promise(resolve => { let routelist = routes.menuRoutes; context.commit('SET_ROUTERS', routelist) resolve() }) } } } export default setrouter 

MainLayout.vue

<template><div><router-view></router-view></div></template><style>.el-container{top:0px;}.el-header{background-color: #B3C0D1;color: #333;line-height: 60px;}.el-aside{color: #333;overflow-y: auto;}</style><script>exportdefault{mounted(){}}</script>

`

修改main.js文件,首页跳转到HkLayout

`

// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import HkLayout from './layout/HkLayout' import router from './router' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import './router/getrouter.js' import axios from 'axios' Vue.use(ElementUI) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { HkLayout }, template: '<HkLayout/>' }) 
Could not load content