有没有办法使用 Vue-Router 从动态 URL 中删除目录?
Is there a way to remove a directory from a dynamic URL using Vue-Router?
我为一家保险经纪公司构建了一个 vue.js 网络应用程序,其中每个代理人都有自己的网站,该网站是根据他们的个人资料生成的。
这就是 link 在我的 vue-router 索引文件中的样子
{
path: '/agents/:id',
name: 'AgentSite',
component: AgentSite
},
一切都很好,除了 url 变得太长而无法在某些名片上显示。我想将 URL 更改为:
{
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]])
})
}
所以,我们的route Id真的是一坨屎
考虑到 id
是数字,您可以使用:
{
path: '/:id(\d+)',
name: 'AgentSite',
component: AgentSite
},
仅当 id
仅由数字组成时才会匹配。
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.
如果名称可能与现有路由冲突,最后声明代理路由。
来自 Matching Priority docs(强调我的):
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
}
]
处理 404 页
Would I then declare the 404 page route above or below the "AgentSite
" in your example? { path: "*", component: PageNotFound }
AgentSite
路由将 匹配之前未匹配的任何 URL ,因此您必须处理 AgentSite
中的 404组件。
首先,在AgentSite
:
之后声明404路由
routes: [
// ... (other routes)
{
path: "/:id",
component: AgentSite,
props: true
},
{
path: ":path",
name: "404",
component: p404,
props: true
}
]
然后,在 AgentSite
中,获取代理 :id
,检查它是否是已知代理,如果不是,则重定向到 404
路由 name(否则会再次匹配agent)
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 已经包含此处理。
如果您 :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>
我为一家保险经纪公司构建了一个 vue.js 网络应用程序,其中每个代理人都有自己的网站,该网站是根据他们的个人资料生成的。
这就是 link 在我的 vue-router 索引文件中的样子
{
path: '/agents/:id',
name: 'AgentSite',
component: AgentSite
},
一切都很好,除了 url 变得太长而无法在某些名片上显示。我想将 URL 更改为:
{
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]])
})
}
所以,我们的route Id真的是一坨屎
考虑到 id
是数字,您可以使用:
{
path: '/:id(\d+)',
name: 'AgentSite',
component: AgentSite
},
仅当 id
仅由数字组成时才会匹配。
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.
如果名称可能与现有路由冲突,最后声明代理路由。
来自 Matching Priority docs(强调我的):
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
}
]
处理 404 页
Would I then declare the 404 page route above or below the "
AgentSite
" in your example?{ path: "*", component: PageNotFound }
AgentSite
路由将 匹配之前未匹配的任何 URL ,因此您必须处理 AgentSite
中的 404组件。
首先,在AgentSite
:
routes: [
// ... (other routes)
{
path: "/:id",
component: AgentSite,
props: true
},
{
path: ":path",
name: "404",
component: p404,
props: true
}
]
然后,在 AgentSite
中,获取代理 :id
,检查它是否是已知代理,如果不是,则重定向到 404
路由 name(否则会再次匹配agent)
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 已经包含此处理。
如果您 :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>