2019-04-03 Vue路由篇之 动动动动动态路由

这次老板的需求是 路由通过后端配置好 直接给我一个路由树 生成侧边栏 ,也就是说 现在前端并不需要控制权限了,没了角色的概念,路由完全靠后端给我,给我什么我就生成什么。
这就有点匪夷所思,讲道理这套框架就是根据角色去筛选路由表,然后前端渲染,现在改写了路由逻辑,我是很蒙蔽的。既然需求就这样,废话不多说了,直接开干。
项目就是老一套 基于vue-element-admin panjiachen大神的框架做的
首先我们找到permission路由守卫这里 原项目这个文件是来控制路由前的一些校验


image.png

我们找到vuex里响应异步获取路由表"GenerateRoutes"的方法


image.png

可以看到这里是使用filterAsyncRouter这个方法 根据角色 不断递归筛选路由表
image.png

根据pan大神的思路 我自己改写了一下筛选方法(自己倒腾了好久才发现人家其实有类似方法了) 遍历后台传来的路由字符串,转换为组件对象
可以注意到
route.component = () => import('@/views/documentation/index.vue')

这个我是写死的路径 将后台传来的字符串替换为组件
layout直接导入就OK了

...
import Layout from '@/views/layout/Layout'
...
function filterAsyncRouter(asyncRouterMap) { // 遍历后台传来的路由字符串,转换为组件对象
  const accessedRouters = asyncRouterMap.filter(route => {
    if (route.component) {
      if (route.component === 'Layout') { // Layout组件特殊处理
        route.component = Layout
      } else {
        console.log(route.component)
        route.component = () => import('@/views/documentation/index.vue')
      }
    }
    if (route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children)
    }
    return true
  })

  return accessedRouters
}

以下是我用easy-mock自己模拟的路由树

{
  "data": {
    "router": [
      {
        "path": "/documentation",
        "component": "Layout",
        "redirect": "/documentation/index",
        "children": [
          {
            "path": "index",
            "component": "documentation/index",
            "name": "Documentation",
            "meta": {
              "title": "documentation",
              "icon": "documentation",
              "noCache": true
            }
          }
        ]
      }
    ]
  }
}
这是后台传来的路由渲染出来的

按理说到现在 已经可以动态挂载路由了吧? 那你就错了 看到我上边组件是写死的路径了吗 实际应用场景我们需要把他替换为一个变量 就像这样:

function filterAsyncRouter(asyncRouterMap) {
  const accessedRouters = asyncRouterMap.filter(route => {
    if (route.component) {
      if (route.component === 'Layout') {
        route.component = Layout
      } else {
        route.component = () => import(`@/views/${route.component}.vue`) // 就像这样 这个变了打印出来就是documentation/index这个字符串
      }
    }
    if (route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children)
    }
    return true
  })

  return accessedRouters
}

then...


找不到组件?

原因其实是 webpack的现在的实现方式不能实现完全动态。
看看控制台编译后的文件 其实也会被转为一个异步方法


编译后

在查阅了资料(issue...)后 原来如果想要完全使用动态路由 需要把后台传回来的name 和 本地components 做一个映射
//maprouters.js
// 异步取到的路由 router.components的name 和 本地components map 做一个映射
const dynamicRouterMap = {
  'documentation/index': () => import(`@/views/documentation/index.vue`),
  'nested/menu1/index': () => import(`@/views/nested/menu1/index.vue`),
  'nested/menu2/index': () => import(`@/views/nested/menu2/index.vue`)
}
export default { dynamicRouterMap }
// permission.js
...
import DynamicRouterMap from '@/router/maprouters.js'
...
function filterAsyncRouter(asyncRouterMap) { // 遍历后台传来的路由字符串,转换为组件对象
  const accessedRouters = asyncRouterMap.filter(route => {
    if (route.component) {
      if (route.component === 'Layout') { // Layout组件特殊处理
        route.component = Layout
      } else {
        route.component = DynamicRouterMap.dynamicRouterMap[route.component] // 路由映射
      }
    }
    if (route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children)
    }
    return true
  })

  return accessedRouters
}
OJBK

关于作者


  var myproject = {

    nickName  : "remix_huang",

    site : "https://www.jianshu.com/u/717e2ca57b3f"

  }

你可能感兴趣的:(2019-04-03 Vue路由篇之 动动动动动态路由)