【问题标题】:Custom handling forward slashes in vue router ids自定义处理 vue 路由器 ID 中的正斜杠
【发布时间】:2018-12-09 23:46:09
【问题描述】:

我有一个用例需要 vue 路由的 id 部分包含未转义的正斜杠。

我现在的路线是这样的:

{
    path: '/browse/:path*',
    component: browse,
    name: 'browse',
    displayName: 'Browse',
    meta: { title: 'Browse' },
},

所以当用户浏览到上面的url时,会显示浏览组件。

但是,我想使用路径的 id 部分 (:path*) 来包含一个可嵌套的字段系统,例如我的浏览页面使用的路径。

例如,url /browse/project/project1 会在我的树中将我带到 project1 项的两层。

现在,我遇到的问题是 vue 路由器在以编程方式导航时正在转义我的 id(路径),我的 url 最终是这样的:/browse/project%2Fproject1。这是不理想的,对最终用户来说并不好看。此外,如果用户确实手动浏览到/browse/project/project1,应用程序将正常运行,甚至在 url 栏中保留原始编码。

所以我可以通过创建任意数量的子路径来解决这个问题,并希望系统永远不会超过这些,但这不是解决我的问题的好方法。

我还应该澄清一下,应用程序不会知道/browse 之后的路径,因为它是由为应用程序提供支持的 api 动态生成的。

vue-router 中是否有本地方式来处理这个问题?还是我应该改变我做事的方式。

【问题讨论】:

    标签: vue.js vue-router


    【解决方案1】:

    有一个更优雅的解决方案,无需变通方法。

    Vue 路由器在底层使用 path-to-regexp 模块和类似的结构

    const regexp = pathToRegexp('/browse/:path*')
    // keys = [{ name: 'browse', delimiter: '/', optional: true, repeat: true }]
    

    https://github.com/pillarjs/path-to-regexp#zero-or-more

    const regexp = pathToRegexp('/browse/:path+')
    // keys = [{ name: 'browse', delimiter: '/', optional: false, repeat: true }]
    

    https://github.com/pillarjs/path-to-regexp#one-or-more

    重复标志设置为true。任何带有 repeat 标志的数组参数都将与分隔符连接(默认为'/')。

    因此您可以将拆分后的数组 ['project','project1'] 而不是 'project/project1' 传递给 router.push()

    router.push( {name: 'browse', params: {path: ['project','project1']}} ); 
    

    router.push( {name: 'browse', params: {path: 'project/project1'.split('/')}} );
    

    【讨论】:

      【解决方案2】:

      所以我设法通过一些技巧“修复”了这个问题。

      在创建我的 Vue 路由器实例时,我附加了一个 beforeEach 函数来替换任何传出的“/”编码。这会将我正在寻找的“正确”网址发送给客户。

      const router = new Router({
          mode: 'history',
          routes,
      });
      
      router.beforeEach((to, from, next) => {
          // hack to allow for forward slashes in path ids
          if (to.fullPath.includes('%2F')) {
              next(to.fullPath.replace('%2F', '/'));
          }
          next();
      });
      

      【讨论】:

        【解决方案3】:

        我只是在遇到类似问题时偶然发现了您的问题。

        认为这是因为 id 应标识单个资源,而不是资源的嵌套结构/路径。

        虽然我的问题还没有解决,但您可能想要使用 customQueryString:

        https://router.vuejs.org/api/#parsequery-stringifyquery

        https://discourse.algolia.com/t/active-url-with-vue-router-for-facet-and-queries/3399

        【讨论】:

        • 如果对您有帮助,我已添加我的“修复”作为答案。它可能应该更具体一点,因为我只需要为单个子路由删除此编码,但主体有效。
        • 哈哈,我最终使用了相同的 hack,只是使用了 Regex :D .replace(/%2F/g, '/')
        【解决方案4】:

        我通过创建帮助器来为 vue 路由器链接的 :to 属性生成 href 来修复它。

        首先我让路由器可以访问我的新助手服务,就像这里Access router instance from my service

        然后我创建了router-helpers.js,在这里我创建了我的助手,这是一个示例

        import Vue from 'vue'
        import router from '../router.js'
        
        // replace %2F in link by /
        const hrefFixes = function(to) {
          return to.replace(/%2F/g, '/')
        }
        
        // my link helper
        Vue.prototype.$linkExample = attr => {
          // create "to" object for router resolve
          const to = { name: `route-name`, params: { param1: attr } }
        
          // this will resolve "to" object, return href param as string
          // and then i can replace %2F in that string
          return hrefFixes(router.resolve(to).href)
        }
        

        只需在您的 Vue 应用程序中包含此服务一次,然后就可以像这样使用此帮助器

        <router-link :to="$linkExample(attr)">text</router-link>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-05-22
          • 1970-01-01
          • 2020-05-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-04
          • 1970-01-01
          相关资源
          最近更新 更多