有没有办法使用 Vue-Router 从动态 URL 中删除目录?

Posted

技术标签:

【中文标题】有没有办法使用 Vue-Router 从动态 URL 中删除目录?【英文标题】:Is there a way to remove a directory from a dynamic URL using Vue-Router? 【发布时间】:2018-08-31 03:48:44 【问题描述】:

我为保险经纪公司构建了一个 vue.js 网络应用程序,其中每个代理都有自己的网站,该网站是从他们的个人资料生成的。

这是链接在我的 vue-router 索引文件中的样子"


  path: '/agents/:id',
  name: 'AgentSite',
  component: AgentSite
,

除了网址太长而无法放入某些名片之外,一切都很好。我想把网址改成这样:


  path: '/:id',
  name: 'AgentSite',
  component: AgentSite
,

但是,应用程序中的所有其他动态内容都会加载我们的代理网站模板 (AgentSite)。报价单、客户、政策...它们无法正确加载。

有没有办法从 URL 中删除“/agents”而不会弄乱我们应用程序的其余部分?我可以将它缩短为 "/a/:id 但这最终会比它的价值更令人困惑。

谢谢!

编辑:有几个人提到了代理 id 是数字时有效的解决方案。这是一个好主意,只是我们已经构建了代理“slugs”来代替使用。

关于代理网站布局:

created() 
    console.log(this.$route.params.id);
    this.$store.dispatch("getAgentFromSlug", this.$route.params.id);
  

在商店里:

getAgentFromSlug(commit, payload)
  const db = firebase.database();
  db.ref("users/").orderByChild("slug").equalTo(payload).once("value", 
(snap) => 
    console.log(snap.val());
    var info = snap.val();
    commit("setAgentSiteInfo", info[Object.keys(info)[0]])
  )

所以,我们的路由 ID 真的是个蛞蝓。

【问题讨论】:

那些蛞蝓的格式怎么样? 【参考方案1】:

考虑到ids 是数字,您可以使用:


  path: '/:id(\\d+)',
  name: 'AgentSite',
  component: AgentSite
,

仅当 id 仅由数字组成时才匹配。

更新:一些人提到了代理 ID 为数字时有效的解决方案。这是一个好主意,只是我们已经构建了代理“slugs”来代替使用。

如果名称可能与现有路由冲突,最后声明代理路由

来自Matching Priority docs(强调我的):

匹配优先级

有时同一个 URL 可能会被多个路由匹配。在这样一个 case 匹配优先级由路由的顺序决定 定义:路由定义越早,优先级越高 得到

换句话说,声明如下:

  routes: [
    
      path: '/',
      component: HomePage
    ,
    
      path: '/quotes',
      component: Quotes
    ,
    
      path: '/clients',
      component: Clients
    ,
    
      path: '/:id',
      component: AgentSite,
      props: true
    
  ]

CodeSandbox demo Here

处理 404 页面

然后我会在您的示例中将 404 页面路由声明在“AgentSite”之上还是之下? path: "*", component: PageNotFound

AgentSite 路由将匹配任何以前不匹配的 URL,因此您必须处理 AgentSite 组件内的 404。

首先,声明404路由AgentSite:

  routes: [
    // ... (other routes)
    
      path: "/:id",
      component: AgentSite,
      props: true
    ,
    
      path: ":path",
      name: "404",
      component: p404,
      props: true
    
  ]

然后,在AgentSite 中,获取代理:id,检查它是否是已知代理,如果不是,则重定向到404 路由按名称(否则会匹配再次代理)。

export default 
  props: ["id"],
  data() 
    return 
      availableAgents: ["scully", "bond", "nikita"]
    ;
  ,
  created() 
    let isExistingAgent = this.availableAgents.includes(this.id);
    if (!isExistingAgent) 
      this.$router.push(
        name: "404",
        params:  path: this.$route.fullPath.substring(1) 
      );
    
  
;

CodeSandbox demo Here 已包含此处理。

【讨论】:

感谢您的想法...我编辑了原始帖子以显示实际 URL 如何使用 slug 而不是 Id 太棒了,谢谢!关于 404 页面的快速问题......然后我会在您的示例中在“AgentSite”之上还是之下声明它? path: "*", component: PageNotFound 【参考方案2】:

如果您的 :id 具有特定格式 (example from vue-router repository),您可以使用正则表达式匹配。

例如,如果您的:id 是一个数字:

const routes = [
   path: '/:id(\\d+)', component: Foo ,
   path: '/bar', component: Bar 
]

const Foo =  template: '<div>foo</div>' 
const Bar =  template: '<div>bar</div>' 

const routes = [
   path: '/:id(\\d+)', component: Foo ,
   path: '/bar', component: Bar 
]

const router = new VueRouter(
  routes
)

const app = new Vue(
  router
).$mount('#app')
.router-link-active 
  color: red;
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <router-link to="/321321">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>

  <router-view></router-view>
</div>

【讨论】:

感谢您的想法...我编辑了原始帖子以显示实际 URL 如何使用 slug 而不是 Id 好吧,我预料到您使用的是蛞蝓,所以我尝试搜索解决方案。我发现^(?!contact|about-us).* regex (regexr.com/3ml3d) 可以工作,但是 vue.js 使用pillarjs/path-to-regex 库来匹配这些正则表达式和组匹配是有问题的。这是不可能的。看github.com/pillarjs/path-to-regexp/issues/95。

以上是关于有没有办法使用 Vue-Router 从动态 URL 中删除目录?的主要内容,如果未能解决你的问题,请参考以下文章

UOJ#22UR #1外星人(动态规划)

vue-router 2,如何通过 ajax 获取路由?

UR #5怎样更有力气

使用vue-router 刷新 404错误

如何在 Vue-router 中使用 addroutes 方法?

有没有办法隐藏或编码 url 路径?