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

Vue后台获取路由信息

模拟后台返回路由JSON数据

java 复制代码
export const menuRouterMap = [
  {name:'menu', path: '/home/menu',compPath:'components/Menu'}
]

常量路由文件数据

constant.js

java 复制代码
import HelloWorld from '@/components/HelloWorld'
export const constantRouterMap = [
  {
    path: '/HelloWorld',
    name: 'HelloWorld',
  }
]

/router/index.js

java 复制代码
import Vue from 'vue'
import Router from 'vue-router'
import {constantRouterMap} from './constant.js'
Vue.use(Router)

const router = new Router({
  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生成路由树状结构

java 复制代码
import Vue from 'vue'
import store from '@/store'
import router from './index.js'
import MainLayout 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

java 复制代码
import Vue from 'vue'
import Vuex from 'vuex'
import setrouter from './setrouter'
Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    setrouter
  },
  state: {
  },
  mutations: {
  },
  actions: {
  },
  getters: {
    setrouter: state => state.setrouter.setrouter,
  }
})

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

java 复制代码
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

路由视图文件

HkLayout.vue

html 复制代码
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

html 复制代码
<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>
export default {
    mounted() {

    }
}
</script>

`

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

`

html 复制代码
// 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/>'
})
相关推荐
cch89182 小时前
PHP vs Vue.js:后端与前端的终极对比
前端·vue.js·php
我命由我123452 小时前
Vue3 开发中,字符串中的 <br\> 标签被直接当作文本显示出来了,而不是被解析为 HTML 换行标签
开发语言·前端·javascript·vue.js·html·ecmascript·html5
北风toto3 小时前
Vue多文件学习项目综合案例——面经基础版,黑马vue教程
javascript·vue.js·学习
徐小夕11 小时前
我用 AI 撸了个开源"万能预览器":浏览器直接打开 Office、CAD 和 3D 模型
前端·vue.js·github
前端Hardy16 小时前
字节/腾讯内部流出!Claude Code 2026王炸玩法!效率暴涨10倍
前端·javascript·vue.js
逆光如雪20 小时前
移动端卡片边框怎么做高级?我用 CSS 实现了设计师的刁钻要求
前端·css·vue.js
莹宝思密达20 小时前
地图显示西安经济开发区边界线-2023.12
前端·vue.js·数据可视化
leafyyuki21 小时前
告别 Vuex 的繁琐!Pinia 如何以更优雅的方式重塑 Vue 状态管理
前端·javascript·vue.js
Hooray21 小时前
AI 时代的管理后台框架,应该是什么样子?
前端·vue.js·ai编程