有没有办法使用 Vue-Router 从动态 URL 中删除目录? [英] Is there a way to remove a directory from a dynamic URL using Vue-Router?
问题描述
我为一家保险经纪公司构建了一个 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 id
s 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
}
]
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屋!