美文网首页Vue.jsVue.js专区
Vue Router 相对路径转绝对路径

Vue Router 相对路径转绝对路径

作者: 於風聽語 | 来源:发表于2019-09-29 12:14 被阅读0次

    因为 Vue Router 支持 嵌套路由,所以愉快的写起了相对路径。

    const router = new VueRouter({
      routes: [
        { path: '/user', component: User,
          children: [
            {
              // 当 /user/profile 匹配成功,
              // UserProfile 会被渲染在 User 的 <router-view> 中
              path: 'profile',
              component: UserProfile
            },
            {
              // 当 /user/posts 匹配成功
              // UserPosts 会被渲染在 User 的 <router-view> 中
              path: 'posts',
              component: UserPosts
            }
          ]
        }
      ]
    })
    

    一时相对一时爽,可是此时非彼时。
    想要根据 routes 渲染菜单,菜单就需要路由跳转,而我又没有写 name 命名路由,故如下跳转不可行:

    this.$router.push({ name: 'user' })
    

    可是 this.$router.options.routes 这货也拿不到绝对路径 path,故如下跳转也不可行:

    this.$router.push({ path: '/user' })
    

    何解

    此解有三:

    • 老老实实写绝对路径呗
    • 或者全部上命名路由
    • 或者路由转换成绝对路径

    写绝对内心有点抵触,命名亦是个头疼的事情,那...

    把拿到 this.$router.options.routes 的数据进行重组呗

    • 路径转换(仅针对对 Vue Router 的路径,不考虑 node 那种 path.resolve):
    function resolvePath(...paths) {
      let i = paths.length
    
      // 反向查找 / 开头的路径
      while (--i) {
        if (/^\//.test(paths[i])) break
      }
      
      return paths.slice(i)
        .join('/') // 加入 '/'
        .replace('//', '/') // 替换可能存在的 '//'
    }
    
    • 测试:
    resolvePath('/', 'a', 'cb', '/www/', 'c') // "/www/c"
    resolvePath('/', 'a', 'cb', 'www', 'c') // "/a/cb/www/c"
    

    完整实例

    假设路由:

    const routes = [
      {
        "path": "/",
        "meta": {
          "name": "首页"
        },
        "children": [
          {
            "path": "",
            "redirect": "/dashboard"
          },
          {
            "path": "/dashboard",
            "name": "dashboard",
            "meta": {
              "name": "Dashboard"
            }
          },
          {
            "path": "user",
            "meta": {
              "name": "用户管理"
            },
            "children": [
              {
                "path": "list",
                "meta": {
                  "name": "列表"
                }
              },
              {
                "path": "edit",
                "meta": {
                  "name": "编辑/创建"
                }
              },
              {
                "path": "log",
                "meta": {
                  "name": "日志"
                }
              }
            ]
          }
        ]
      },
      {
        "path": "/auth",
        "name": "auth"
      }
    ]
    

    转换函数:

    function resolvePath ( ...paths ) {
        let i = paths.length
    
        while ( --i ) {
            if ( /^\//.test( paths[i] ) ) break
        }
    
        return paths.slice( i )
            .join( '/' ) // 加入 '/'
            .replace( '//', '/' ) // 替换可能存在的 '//'
    }
    
    function restructure ( routes = [], base = '/' ) {
        return routes.map( route => {
            let { path, children = [] } = route
    
            path = resolvePath( base, path )
    
            if ( children.length > 0 ) {
                route.children = restructure( children, path )
            }
    
            return {
                ...route,
                path
            }
        } )
    }
    
    export default restructure
    

    测试:

     // 假设 this.$router.options = '/'
    const result = restructure (routes, '/')
    
    console.log( JSON.stringify(result, null, 4) )
    
    // 输出
    [
        {
            "path": "/",
            "meta": {
                "name": "首页"
            },
            "children": [
                {
                    "path": "/",
                    "redirect": "/dashboard"
                },
                {
                    "path": "/dashboard",
                    "name": "dashboard",
                    "meta": {
                        "name": "Dashboard"
                    }
                },
                {
                    "path": "/user",
                    "meta": {
                        "name": "用户管理"
                    },
                    "children": [
                        {
                            "path": "/user/list",
                            "meta": {
                                "name": "列表"
                            }
                        },
                        {
                            "path": "/user/edit",
                            "meta": {
                                "name": "编辑/创建"
                            }
                        },
                        {
                            "path": "/user/log",
                            "meta": {
                                "name": "日志"
                            }
                        }
                    ]
                }
            ]
        },
        {
            "path": "/auth",
            "name": "auth"
        }
    ]
    

    ---- Vinci, Sunday, September 29 2019, Sunny

    相关文章

      网友评论

        本文标题:Vue Router 相对路径转绝对路径

        本文链接:https://www.haomeiwen.com/subject/wweauctx.html