zoukankan      html  css  js  c++  java
  • 【vue】iView-admin2.0动态菜单路由【版2】

    依照
    iView-admin2.0动态菜单路由【版1】
    归纳几个节点
    动态路由获取方式2 ——> easymock假数据 ——> 数据转组件处理、addRoutes ——> localStorage存储 ——> 动态路由path刷新

        修改操作--关于动态路由
    1. 删掉src/main.js中mounted调用的初始化动态路由函数initRouter()——————即没做修改的初状态写法即可 ,【版1】去掉修改src/main.js的步骤

    2.新增src/libs/router-util.js做请求动态路由的数据处理,转为路由组件,commit更新updateMenuList[写在src/store/module/app.js]左侧菜单并addRoutes到路由表 

    /**
     * ①添
     * @@新增 定义初始化菜单
     */
    
    import { getToken, localSave, localRead } from '@/libs/util'
    // import config from '@/config'
    import store from '@/store'
    import { lazyLoadingCop } from '@/libs/tools'
    import { mockAntRouter } from '@/api/mockApi'
    import Main from '@/components/main' // Main 是架构组件,不在后台返回,在文件里单独引入
    import parentView from '@/components/parent-view' // parentView 是二级架构组件,不在后台返回,在文件里单独引入
    // const _import = require('@/router/_import_' + process.env.NODE_ENV)// 获取组件的方法
    
    var gotRouter
    // 初始化路由
    export const initRouter = () => {
      let antRouter = localRead('dynamicRouter');
      if (!antRouter) {
        mockAntRouter().then(res => {
          if (res.status === 200) {
            var routerData = res.data.router // 后台拿到路由
            localSave('dynamicRouter', JSON.stringify(routerData)) // 存储路由到localStorage
            gotRouter = filterAsyncRouter(routerData) // 过滤路由,路由组件转换
            store.commit('updateMenuList', gotRouter);
            dynamicRouterAdd()
          } else {
            console.log('请求失败')
          }
        })
      } else {
        gotRouter = dynamicRouterAdd()
      }
      return gotRouter
    }
    
    // 加载路由菜单,从localStorage拿到路由,在创建路由时使用
    export const dynamicRouterAdd = () => {
      let dynamicRouter = []
      let data = localRead('dynamicRouter')
      if (!data) {
        return dynamicRouter
      }
      dynamicRouter = filterAsyncRouter(JSON.parse(data))
      return dynamicRouter
    }
    
    // @函数: 遍历后台传来的路由字符串,转换为组件对象
    export const filterAsyncRouter = (asyncRouterMap) => {
      const accessedRouters = asyncRouterMap.filter(route => {
        if (route.component) {
          if (route.component === 'Main') { // Main组件特殊处理
            route.component = Main
          } else if (route.component === 'parentView') { // parentView组件特殊处理
            route.component = parentView
          } else {
            // route.component = _import(route.component)
            route.component = lazyLoadingCop(route.component)
          }
        }
        if (route.children && route.children.length) {
          route.children = filterAsyncRouter(route.children)
        }
        return true
      })
      return accessedRouters
    }
    View Code

        附加1.  src/libs/tools.js增加 引入组件 封装函数lazyLoadingCop   (此demo暂以此方式)

    //  @函数: 引入组件
    export const lazyLoadingCop = file => require('@/view/' + file + '.vue').default

        附加2. src/router中新增_import_development.js和_import_production.js为引入.vue组件的封装【俩种环境】

       _import_development.js

    module.default = file => require('@/view/' + file + '.vue').default // vue-loader at least v13.0.0+

       _import_production.js

    module.exports = file => () => import('@/view/' + file + '.vue')

    3.修改src/store/module/app.js中getters的menuList函数,左侧显示动态获取的[这样减少了字段hideInMenu,同时menuList存储量也减少了默认的router]

    import {
        .
      getMenuByRouter,
        .
        .
      localSave,
      localRead
    } from '@/libs/util'
        .
        .
    import { dynamicRouterAdd } from '@/libs/router-util' // ①添 引入加载菜单
        .
        .
    export default {
      state: {
        .
        tagNavList: [],
        .
        .
        menuList: []
      },
      getters: {
        // menuList: (state, getters, rootState) => getMenuByRouter(routers, rootState.user.access),//初始
        menuList: (state, getters, rootState) => getMenuByRouter(dynamicRouterAdd(), rootState.user.access), // ①改 通过路由列表得到菜单列表
      },
      mutations: {
        . 
        .
        updateMenuList (state, routes) { // ①添 接受前台数组,刷新菜单
          console.log(state, routes, 'updateMenuList')
          router.addRoutes(routes); // 动态添加路由
          state.menuList = routes;
        }
      },
        . 
        .
    }
    View Code

    4.src/router/router.js引入dynamicRouterAdd,在routes初始创建时调用dynamicRouterAdd()服务于减少动态路由的异步请求

    import Main from '@/components/main'
    import { dynamicRouterAdd } from '@/libs/router-util' // ①添 引入加载菜单
    
    /**
     * iview-admin中meta除了原生参数外可配置的参数:
     * meta: {
     *  title: { String|Number|Function }
     *         显示在侧边栏、面包屑和标签栏的文字
     *         使用'{{ 多语言字段 }}'形式结合多语言使用,例子看多语言的路由配置;
     *         可以传入一个回调函数,参数是当前路由对象,例子看动态路由和带参路由
     *  hideInBread: (false) 设为true后此级路由将不会出现在面包屑中,示例看QQ群路由配置
     *  hideInMenu: (false) 设为true后在左侧菜单不会显示该页面选项
     *  notCache: (false) 设为true后页面在切换标签后不会缓存,如果需要缓存,无需设置这个字段,而且需要设置页面组件name属性和路由配置的name一致
     *  access: (null) 可访问该页面的权限数组,当前路由设置的权限会影响子路由
     *  icon: (-) 该页面在左侧菜单、面包屑和标签导航处显示的图标,如果是自定义图标,需要在图标名称前加下划线'_'
     *  beforeCloseName: (-) 设置该字段,则在关闭当前tab页时会去'@/router/before-close.js'里寻找该字段名对应的方法,作为关闭前的钩子函数
     * }
     */
    // 不作为Main组件的子页面展示的页面单独写
    export const otherRouter = [{
      path: '/login',
      name: 'login',
      meta: {
        title: 'Login - 登录',
        hideInMenu: true
      },
      component: () => import('@/view/login/login.vue')
    }, {
      path: '/401',
      name: 'error_401',
      meta: {
        hideInMenu: true
      },
      component: () => import('@/view/error-page/401.vue')
    }, {
      path: '/500',
      meta: {
        title: '500-服务端错误'
      },
      name: 'error_500',
      component: () => import('@/view/error-page/500.vue')
    }
    ];
    
    // 作为Main组件的子页面展示但是不在左侧菜单显示的路由写在mainRouter里
    export const mainRouter = [{
      path: '/',
      name: '_home',
      redirect: '/home',
      component: Main,
      meta: {
        hideInMenu: true,
        notCache: true
      },
      children: [
        {
          path: '/home',
          name: 'home',
          meta: {
            hideInMenu: true,
            title: '首页',
            notCache: true,
            icon: 'md-home'
          },
          component: () => import('@/view/single-page/home')
        }
      ]
    }, {
      path: '/message',
      name: 'message',
      component: Main,
      meta: {
        hideInBread: true,
        hideInMenu: true
      },
      children: [
        {
          path: 'message_page',
          name: 'message_page',
          meta: {
            icon: 'md-notifications',
            title: '消息中心'
          },
          component: () => import('@/view/single-page/message/index.vue')
        }
      ]
    }];
    
    // 作为Main组件的子页面展示并且在左侧菜单显示的路由写在appRouter里
    export const appRouter = [...dynamicRouterAdd()];
    
    export const routes = [
      ...otherRouter,
      ...mainRouter,
      ...appRouter
    ]
    
    // 所有上面定义的路由都要写在下面输出
    export default routes
    View Code

    5.src/router/index.js引入initRouter,在router.beforeEach路由跳转前调用initRouter()服务于动态路由页的跳转/刷新

    .
    .
    .
    import { initRouter } from '@/libs/router-util'
    
    .
    .
    
    router.beforeEach((to, from, next) => {
    .
      if (!token && to.name !== LOGIN_PAGE_NAME) {
    .
    .
    .
      } else {
        initRouter()
    .
    .
    .
      }
    })
    
    .
    .
    
    export default router
    View Code

    6.src/store/module/user.js引入initRouter,在handleLogin登录时调用initRouter()用于初始请求动态路由及其处理等;在handleLogOut登出时localSave('dynamicRouter',[])清空本地存储localStorage中的dynamicRouter

      附加. 登出操作清空tagNaveList快捷导航:src/store/module/user.js中,handleLogOut登出时localSave('tagNaveList',[]) //清空localStorage中的tagNaveList记录

    .
    .
    import { initRouter } from '@/libs/router-util' // ①添 引入加载菜单
    
    export default {
    .
    .
    .
      actions: {
        // 登录
        handleLogin ({ commit }, { userName, password }) {
          userName = userName.trim()
          return new Promise((resolve, reject) => {
            login({
              userName,
              password
            }).then(res => {
    .
    .
              initRouter()
    .
    .
            }).catch(err => {
              reject(err)
            })
          })
        },
        // 退出登录
        handleLogOut ({ state, commit }) {
          return new Promise((resolve, reject) => {
            logout(state.token).then(() => {
    .
    .
    .
              localSave('dynamicRouter',[])
              localSave('tagNaveList',[]) //清空localStorage中的tagNaveList记录
              resolve()
            }).catch(err => {
              reject(err)
            })
    .
          })
        }
    .
    .
    .
      }
    }
    View Code

    修改操作--其他

    7.左侧菜单显示中文,是否使用国际化vue-i18n:默认为false。 src/config/index.js中修改useI18n: false

    经过反复测试,此修复版动态路由菜单成功显示,跳转,刷新,清空。

    喜欢就点个推荐吧~

     

  • 相关阅读:
    通过微软的HTML Help Workshop 利用.html文件 生成简单的chm帮助类的文件
    CHM编写软件
    tinyxml使用笔记与总结
    UCOS源码剖析 (一)
    灵性领悟的四个阶段-肯·威尔伯
    ans menu list
    lxm --- ans lb config
    macvtap介绍
    影子系统密码忘记
    Linux环境安装.NET运行环境
  • 原文地址:https://www.cnblogs.com/smilexumu/p/10911161.html
Copyright © 2011-2022 走看看