有没有办法使用 Vue-Router 从动态 URL 中删除目录? [英] Is there a way to remove a directory from a dynamic URL using Vue-Router?

查看:51
本文介绍了有没有办法使用 Vue-Router 从动态 URL 中删除目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've build a vue.js web app for an insurance brokerage where every agent has their own website that is generated from their profiles.

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

This is what the link looks like in my vue-router index file"

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

一切都很好,除了网址太长而无法放在某些名片上.我想将 URL 更改为如下所示:

Everything works great EXCEPT that the urls are getting too long to fit on some business cards. I would like to change the URLs to be like this:

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

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

However, then every other bit of dynamic content in the app loads our agent website template (AgentSite). Quotes, Clients, Policies... they won't load properly.

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

Is there a way to remove the "/agents" from the URLs without messing up the rest of our application? I could shorten it to "/a/:id but that ends up being more confusing than it's worth.

谢谢!

有几个人提到了当代理 ID 是数字时有效的解决方案.这是个好主意,只是我们已经构建了代理slugs"来代替使用.

a couple of people have mentioned solutions that work when the agent id is a number. That's a great idea except that we have built agent "slugs" to use instead.

在代理网站布局上:

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 确实是一个 slug.

So, our route Id is really a slug.

推荐答案

考虑到 id 是数字,你可以使用:

Considering ids are numbers, you could use:

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

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

Which only matches if id is made only of numbers.

更新:有几个人提到了当代理 ID 是数字时有效的解决方案.这是个好主意,只是我们已经构建了代理slugs"来代替使用.

Update: A couple of people have mentioned solutions that work when the agent id is a number. That's a great idea except that we have built agent "slugs" to use instead.

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

If the names can conflict with existing routes, declare the agent route last.

来自匹配优先级文档(强调我的):

From the Matching Priority docs (emphasis mine):

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

Matching Priority

Sometimes the same URL may be matched by multiple routes. In such a case the matching priority is determined by the order of route definition: the earlier a route is defined, the higher priority it gets.

换句话说,声明如下:

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

请参阅此处为 CodeSandbox 演示.

See CodeSandbox demo Here.


然后我会在您的示例中在AgentSite"上方或下方声明 404 页面路由吗?{ path: "*", component: PageNotFound }

Would I then declare the 404 page route above or below the "AgentSite" in your example? { path: "*", component: PageNotFound }

AgentSite 路由将匹配之前未匹配的任何 URL,因此您必须在 AgentSite 组件内处理 404.

The AgentSite route would match any URL not matched previously, so you'll have to handle the 404s inside the AgentSite component.

首先,在AgentSite之后声明404路由:

First, declare the 404 route after the AgentSite:

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

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

Then, inside AgentSite, get the agent :id, check if it is a known agent and, if not, redirect to the 404 route by name (otherwise it would match agent again).

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 演示在这里 已经包含此处理.

The CodeSandbox demo Here already contains this handling.

这篇关于有没有办法使用 Vue-Router 从动态 URL 中删除目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆