自定义处理 vue 路由器 ID 中的正斜杠

Custom handling forward slashes in vue router ids

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

我当前的路线是这样的:

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

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

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

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

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

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

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

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

我刚刚在遇到类似问题时偶然发现了你的问题。

认为这是因为 id 应标识一个资源而不是资源的嵌套 structure/path。

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

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

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

所以我设法 'fix' 通过一些 hack。

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

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();
});

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

首先,我让路由器可以访问我的新助手服务,就像这里

然后我创建了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>

有一个没有变通办法的更优雅的解决方案。

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('/')}} );