VUE动态加载菜单

1、后端接口返回菜单路径等(和router.js中的格式一样)

2、前端动态渲染

2.1、vuex配置

import Vue from 'vue'
import Vuex from 'vuex'
// vuex状态管理工具
Vue.use(Vuex)

export default new Vuex.Store({
        state:{
            routes: []
        },
        mutations:{
            initRoutes(state,data) {
                state.routes = data;
            }
        },
        actions:{

        }
    })

2.2、菜单工具类(用于解析后端返回的json菜单)

// 菜单工具类,用于将后端返回的菜单格式化为符合路由写法的格式
import {getRequest} from "./api";
// 加载所有菜单
export const initMenu=(router,store) => {

    if (store.state.routes.length > 0) {
        return;
    }


    getRequest("/system/config/menu").then(
        data=>{
            if (data) {
                let fmtRoutes = formatRoutes(data);
                router.addRoutes(fmtRoutes);
                store.commit('initRoutes', fmtRoutes);
            }
        }
    )
}

export const formatRoutes = (routes) => {
    let fmRoutes = [];
    routes.forEach(router => {
        let {
            path,
            component,
            name,
            meta,
            iconCls,
            children
        } = router;

        if (children && children instanceof Array) {
            children = formatRoutes(children);
        }

        let fmRouter={
            path:path,
            name:name,
            iconCls:iconCls,
            meta:meta,
            children:children,
            component(resolve) {
                if (component.startsWith("Home")) {
                    require(['../views/'+component+'.vue'],resolve); // 动态导入
                } else if (component.startsWith("Emp")) {
                    require(['../views/emp/'+component+'.vue'],resolve); // 动态导入
                } else if (component.startsWith("Per")) {
                    require(['../views/per/'+component+'.vue'],resolve); // 动态导入
                } else if (component.startsWith("Sal")) {
                    require(['../views/sal/'+component+'.vue'],resolve); // 动态导入
                } else if (component.startsWith("Sta")) {
                    require(['../views/sta/'+component+'.vue'],resolve); // 动态导入
                } else if (component.startsWith("Sys")) {
                    require(['../views/sys/'+component+'.vue'],resolve); // 动态导入
                }
            }
        }

        fmRoutes.push(fmRouter)
    })
    return fmRoutes;
}

2.3 、路由增加前置守卫(用于监听加载)

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/Login.vue'
import {initMenu} from "../utils/menus";
import store from "../store";

Vue.use(VueRouter)


// 引入组件
const routes = [
  {
    path: '/',
    name: 'Login',
    component: Login,
    hidden: true
  }
]

const router = new VueRouter({
  routes
})
// 引入前置守卫,类似于过滤器,监听操作
router.beforeEach((to, from, next) => {
  // 防止刷新页面后菜单未加载,添加前置守卫
  if (to.path == '/') {
    next();
  } else {
    initMenu(router,store);
    next();
  }
})
export default router

2.4、使用

                        <!--<el-menu @select="menuClick">-->
                        <el-menu router unique-opened>

                            <!--之前从路由中获取<el-submenu index="1" v-for="(item,index) in this.$router.options.routes" v-if="!item.hidden" :key="index">-->
                            <el-submenu :index="index + ''" v-for="(item,index) in routes" v-if="!item.hidden" :key="index">
                                <template slot="title">

                                    <i class="el-icon-location"></i>
                                    <span>{{item.name}}</span>
                                    <!--<span>test</span>-->
                                </template>
                                <el-menu-item-group>
                                    <el-menu-item :index="child.path" v-for="(child,indexj) in item.children" :key="indexj">{{child.name}}</el-menu-item>
<!--                                    <el-menu-item index="/test1">1</el-menu-item>
                                    <el-menu-item index="/test2">2</el-menu-item>-->
                                </el-menu-item-group>

                            </el-submenu>
                        </el-menu>

版权声明:本文为cz1803472613原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。