问题
VueRouter always adds a trailing slash before the path of the child route. So lets say I have a route config like this:
const routes = [
path: '/home',
components: {
default: HomeBase
},
children: [
{
path: '',
component: HomeIndex,
name: 'home.index'
},
{
path: ':aid',
component: HomeArticle,
name: 'home.article'
}
]
]
I want the routes to work like this:
- /home -> loads HomeIndex
- /home/123 -> Loads HomeArticle with :aid=123
But VueRouter always forces the trailing slash on the parent route path, when accessing a child route, so the routes work like this:
- /home/ -> loads HomeIndex
- /home/123 -> loads HomeArticle with :aid=123
This doesn't work for me, as I'm working with an application that has specific SEO requirements that require no trailing slashes.
Note that I'm using named routes to generate URLs and move between routes, so while I could link to "/home" directly, I want to use the names of routes ( "home.index") so code is more DRY. I could store the paths in constants somewhere, but the drawback of that is that you can't use the 'params' prop together with the 'path' prop when programmatically navigating.
I could split out HomeIndex as a separate path entirely, so its not a child, but I need HomeIndex and HomeArticle both to be loaded within the root HomeBase component.
Any ideas how I could achive this? Maybe through some VueRouter hooks or plugins?
回答1:
I've tried next structure which worked for me:
const routes = [
path: '/home',
components: {
default: HomeBase
},
children: [
{
path: '/home',
component: HomeIndex,
name: "homeindex"
},
{
path: ':aid',
component: HomeArticle,
name: "aid"
}
]
]
Here is the working fiddle
Using versions: Vue - 2.5.2
, vue-router - 3.0.1
. Routing works both using name
and path
without adding trailing slash at the end, i.e.:
this.$router.push({name: "homeindex"})
this.$router.push("/home")
回答2:
from /*
to {name: root}
redirect to /root
renders root.firstchild
Playground below...
named routes -> use redirect
to route your name: home
to name: home.index
- example with renaming for usability
const router = new VueRouter({
routes: [{
path: '/home',
name: 'child1', // cheated child
redirect: '/home', // here point to true child
component: Home,
children: [
{
path: '', // this is accesible by /home !
//name: 'child1',
component: Child1,
},
{
path: ':slug',
name: 'child2',
component: Child2,
}
]
}]
})
So the issue is in your <router-link>
. It has most likely an appended /
thus the path will have one.
Basically if you route
from: /a/b
to /a
it will be /a
from: /a/
to /a
it will be /a/
from: /a
to /a/
it will be /a
to: name: root
it will be /a
without rendering first child
to: name: root.firstChild
it will be /a/
To route to /root
<=> root.firstChild
from anywhere by name you have to route to {name: root} and then redirect to /root
.
from /*
to {name: root}
redirect to /root
renders child
playground
const Home = {
template: "#home"
}
const Child1 = {
template: "#child1"
}
const Child2 = {
template: "#child2"
}
const router = new VueRouter({
routes: [{
path: '/home',
name: 'home',
redirect: '/home',
component: Home,
children: [
{
path: '',
name: 'child1',
component: Child1,
},
{
path: ':slug',
name: 'child2',
component: Child2,
}
]
}]
});
new Vue({
template: "#index",
router
}).$mount('#app');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>
<div id="app">
<router-view></router-view>
</div>
<template id="index">
<div>
Index
<router-link :to="{name: 'home'}">Go to /home</router-link>
<router-link :to="{name: 'child1'}">Go to /home/</router-link>
<router-link :to="{name: 'child2', params: {slug: 'any'}}">Go to /home/slug</router-link>
<router-view></router-view>
</div>
</template>
<template id="home">
<div>
Home
<router-view></router-view>
</div>
</template>
<template id="child1">
<div>{{$route.fullPath}}</div>
</template>
<template id="child2">
<div>{{$route.fullPath}}</div>
</template>
来源:https://stackoverflow.com/questions/58130594/vuerouter-default-child-route-without-trailing-slash