【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
}

附加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;
    }
  },
    . 
    .
}

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

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

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)
        })
.
      })
    }
.
.
.
  }
}

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

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

喜欢就点个推荐吧~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值