• vue2.0后台管理 动态加载菜单


    最近接手一个后台管理项目,需要实现从后台拉取导航菜单的效果;根据不同的登录用户的权限分别拉取不同的导航菜单,进行页面的跳转

    实现方法:

    从后台返回菜单与动态路由的数组做匹配,选择需要动态加载的路由,在将后台返回的菜单加载到页面即可

    1.首先在本地固定配置好不变的路由的地址,例如登录,404,403,500等公用页面

    const constantRouterMap = [
    {
    path:'/login',
    name:'Login',
    component:Login
    },
    {
    path: '/',
    name:'',
    component:layout,
    redirect: '/home',
    children:[
    { path:'/home',
    component:home,
    name:'首页页面',
    meta:{
    close:false
    }
    }
    ]
    },
    {
    path: "/500",
    name: "serverError",
    component: serverError
    },
    {
    path: "/403",
    name: "notPermission",
    component: notPermission
    },
    {
    path: "/404",
    name: "notFound",
    component: notFound
    },
    {
    path: "*", // 此处需特别注意置于最底部
    redirect: "/404"
    }
    ]

    2.动态加载的菜单配置

    //动态加载的路由
    const asyncRouterMap = [
    {
    path:'/sys/user',
    component:sys_user,
    name:'用户权限',
    meta:{
    close:true
    }
    },
    {
    path:'/sys/sysPermission',
    component:sys_menu,
    name:'权限管理',
    meta:{
    close:true
    }
    },
    {
    path:'/sys/role',
    component:sys_role,
    name:'角色管理',
    meta:{
    close:true
    }
    },
    {
    path:'/sys/appMenu',
    component:sys_dept,
    name:'菜单管理',
    meta:{
    close:true
    }
    },
    {
    path:'/dict',
    component:dict,
    name:'字典管理',
    meta:{
    close:true
    }
    }
    ]
    3.利用后台返回的菜单的格式
    {"code":200,"msg":"success","data":[{"id":"2","isNewRecord":false,"createDate":"2013-05-27 08:00:00","updateDate":"2013-05-27 08:00:00","parentIds":"0,1,","name":"系统设置","sort":900,"isShow":"1","isApp":"0","children":[{"id":"44c896e862264fc883b7dbe35a56ea55","isNewRecord":false,"remarks":"","createDate":"2017-03-06 20:59:16","updateDate":"2017-11-29 14:51:12","parentIds":"0,1,2,","name":"组织机构","href":"","target":"","icon":"","sort":10,"isShow":"1","permission":"","isApp":"0","children":[{"id":"17","isNewRecord":false,"remarks":"","createDate":"2013-05-27 08:00:00","updateDate":"2017-03-06 21:00:01","parentIds":"0,1,2,44c896e862264fc883b7dbe35a56ea55,","name":"机构管理","href":"/sys/office","target":"","icon":"th-large","sort":40,"isShow":"1","permission":"","isApp":"0","children":[],"parentId":"44c896e862264fc883b7dbe35a56ea55"},{"id":"20","isNewRecord":false,"remarks":"","createDate":"2013-05-27 08:00:00","updateDate":"2017-03-06 21:00:29","parentIds":"0,1,2,44c896e862264fc883b7dbe35a56ea55,","name":"人员管理","href":"/sys/user","target":"","icon":"user","sort":50,"isShow":"1","permission":"","isApp":"0","children":[],"parentId":"44c896e862264fc883b7dbe35a56ea55"}],"parentId":"2"},{"id":"3","isNewRecord":false,"createDate":"2013-05-27 08:00:00","updateDate":"2013-05-27 08:00:00","parentIds":"0,1,2,","name":"系统设置","sort":20,"isShow":"1","isApp":"0","children":[{"id":"4","isNewRecord":false,"remarks":"","createDate":"2013-05-27 08:00:00","updateDate":"2017-12-18 11:09:05","parentIds":"0,1,2,3,","name":"PC菜单管理","href":"/sys/webMenu","target":"","icon":"list-ul","sort":30,"isShow":"1","permission":"","isApp":"0","children":[],"parentId":"3"},{"id":"8f0210e672a54b0282d08ce3a9259c66","isNewRecord":false,"remarks":"","createDate":"2017-12-18 10:28:22","updateDate":"2017-12-18 11:09:55","parentIds":"0,1,2,3,","name":"APP菜单管理","href":"/sys/appMenu","target":"","icon":"list","sort":40,"isShow":"1","permission":"","isApp":"0","children":[],"parentId":"3"},{"id":"7","isNewRecord":false,"remarks":"","createDate":"2013-05-27 08:00:00","updateDate":"2017-11-30 13:38:50","parentIds":"0,1,2,3,","name":"角色管理","href":"/sys/role","target":"","icon":"group","sort":50,"isShow":"1","permission":"","isApp":"0","children":[],"parentId":"3"}],"parentId":"2"}],"parentId":"1"}]}
    4.通过一个函数将菜单与动态的路由做匹配
    export function filterAsyncRouter(asyncRouterMap=[],menuTree=[]){
    const res = []
    const routers = getRoute(menuTree)
    asyncRouterMap.forEach((route)=>{
    var routeItem = route
    routers.forEach((item)=>{
    if(item.href==routeItem.path){
    //将后台返回的name赋值给前台定义好的
    routeItem.name = item.name
    res.push(routeItem)
    }
    })
    })
    return res;
    }

    5.利用路由的addRouter的特性将于菜单匹配到的路由加载到路由中

      let asyncRouterMaps = filterAsyncRouter(asyncRouterMap,store.state.navTree)

    asyncRouterMaps.forEach((route)=>{
    router.options.routes[1].children.push(route)
    })
    router.addRoutes(router.options.routes)

    6.再将后台返回的菜单加载到页面中即可:
    menuTree.vue加载一个菜单的component

    <template>
      <el-submenu v-if="menu.children && menu.children.length >= 1" :index="'' + menu.id">
    <template slot="title">
    <i :class="menu.icon" ></i>
    <span slot="title">{{menu.name}}</span>
    </template>
    <MenuTree v-for="item in menu.children" :key="item.id" :menu="item"></MenuTree>
    </el-submenu>
    <el-menu-item v-else :index="(menu.href?menu.href:menu.id)">
    <i :class="menu.icon"></i>
    <span slot="title">{{menu.name}}</span>
    </el-menu-item>
    </template>
    在home的navbar中引用到需要的地方即可
    <template>
    <!--导航栏部分-->
    <aside :class="collapsed?'menu-collapsed':'menu-expanded'">
    <el-menu ref="navmenu" :default-active="$router.history.current.path" router unique-opened class="el-menu-vertical-demo" @select="handleSelect" @open="handleOpen" @close="handleClose" :collapse="collapsed">
    <menu-tree v-for="item in navTree" :key="item.id" :menu="item"></menu-tree>
    </el-menu>
    </aside>
    </template>

    <style>
    .el-menu-vertical-demo:not(.el-menu--collapse) {
    230px;
    }
    </style>

    <script>
    import store from '@/store'
    import router from '@/router'
    import {mapState} from 'vuex'
    import MenuTree from '@/components/menuTree'
    import { setTab,getTab } from '@/utils/auth'
    export default {
    data() {
    return {
    navTree:this.$store.state.navTree,
    };
    },
    components:{
    MenuTree
    },
    watch:{
    '$route':'handleRoute'
    },
    created () {
    this.handleRoute(this.$route)
    },
    methods: {
    handleOpen(key, keyPath) {
    },
    handleClose(key, keyPath) {
    },
    handleSelect(key,keyPath){
    },
    handleRoute(route){
    //标签页选中,如果不存在则先添加
    //检查现有的tab标签中是否存在,通过path去判断
    var tab = this.mainTabs.filter(item => item.name === route.name)[0]
    if(!tab){
    tab = {
    name:route.name,
    title:route.name,
    path:route.path,
    close:route.meta.close
    }
    this.mainTabs = this.mainTabs.concat(tab)
    }
    setTab(this.mainTabs)
    this.mainTabsActiveName = route.name
    // 切换标签页时同步更新高亮菜单
    if(this.$refs.navmenu != null) {
    this.$refs.navmenu.activeIndex = route.path
    this.$refs.navmenu.initOpenedMenu()
    }
    }
    },
    computed:{
    ...mapState({
    collapsed:'collapse',
    }),
    mainTabs:{
    get () { return this.$store.state.mainTabs },
    set (val) { this.$store.commit('getMainTabs', val) }
    },
    mainTabsActiveName: {
    get () { return this.$store.state.mainTabsActiveName },
    set (val) { this.$store.commit('getMainTabsActiveName', val) }
    }
    },
    mounted(){

    }
    }
    </script>

    <style lang="less" scoped>mainTabs
    aside {
    flex:0 0 230px;
    230px;
    // position: absolute;
    // top: 0px;
    // bottom: 0px;
    .el-menu{
    height: 100%;
    background: #eef1f6;
    }
    .collapsed{
    64px;
    .item{
    position: relative;
    }
    .submenu{
    position:absolute;
    top:0px;
    left:64px;
    z-index:99999;
    height:auto;
    display:none;
    }
    }
    }
    .menu-collapsed{
    flex:0 0 64px;
    64px;
    }
    .menu-expanded{
    flex:0 0 230px;
    230px;
    }
    </style>
    利用次思想就可以形成一个简单的动态加载的例子

  • 相关阅读:
    codevs1231 最优布线问题
    P1352 没有上司的舞会——树形DP入门
    codevs1961 躲避大龙
    codevs2833 奇怪的梦境
    linux 内存管理——内核的shmall 和shmmax 参数
    删除共享内存后key为0x00000000的问题
    redis命令之lrange
    vim配置vimrc详解
    chmod chgrp chown
    localtime和localtime_r
  • 原文地址:https://www.cnblogs.com/orange2013/p/10520632.html
Copyright © 2020-2023  润新知