VueRouter default child route without trailing slash

隐身守侯 提交于 2020-06-27 09:44:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!