Vue-router: [next] active links: allow trailing slash in route matching (nested routes)

Created on 31 Aug 2016  路  18Comments  路  Source: vuejs/vue-router

I would like to have nested routes with a default component in the nested-root like so:

routes: [
  { 
    path: '/home', 
    name: 'home',
    component: Home,
    children: [
      {
        path: '',
        name: 'home.index',
        component: HomeIndex
      },
      {
        path: 'foo',
        name: 'home.foo',
        component: HomeFoo
      }
    ]
  }
]

For the active link highlights i'd like to scope the children separately. Can we serve the same content on both /home and /home/ and have the /home link active in both cases?

Vue.js & vue-router.js version

2.0.0-rc.4, 2.0.0-rc.4

Reproduction Link

https://jsfiddle.net/jwahdatehagh/44ed5xxf/1/

bug

Most helpful comment

@jwahdatehagh Understood. I'll submit a PR shortly.

All 18 comments

I think this should be working as you describe. Currently it doesnt' because with do a simple === match of the path strings here:

https://github.com/vuejs/vue-router/blob/next/src/util/route.js#L8

We could maybe solve this with:

return (
      a.path.replace(/\/$/,'') === b.path.replace(/\/$/,'') &&
      a.hash === b.hash &&
      isObjectEqual(a.query, b.query)
    )

@fnlctrl What are your thoughts?

Does the same problem not apply to a.hash === b.hash? Sorry, i'm not quite acquainted with the internals of the router.

In what way? hashes don't have this issue with optional trailing slashes. hashes come _after_ the path and don't have any slashes:

http://domain.tld/some/path/#hash?query=params

I thought this check is for when the router uses the hash vs the history api e.g. domain.tld#/home/foo.

Then the same issue would occur for #/home vs #/home/.

The hash is removed before route matching:

https://github.com/vuejs/vue-router/blob/next/src/history/hash.js#L44

(the getHash() function does it...)

So when the code reaches the section discussed previously, any hash present is a "real" hash, not a "fake path" hash.

Ok, cool! Thanks for the explanation!

@linusborg Though unlikely, a.path.replace(/\/$/,'') === b.path.replace(/\/$/,'') will be true for '/foo/bar' and '/foobar'.

I don't quite get what OP wants... What's wrong with adding exact on roter-link?

@fnlctrl

  1. my Regex will only remove trailing slashes, so your example should not be possible.
  2. The problem is that a router-link with a path of /home and the exact attribute will _not_ get the activeClass set if the current route's path is /home/ - even though both routes render the same components and should therefore be considered equal in my opinion.

@linusborg Oops, misread that regex...sorry.
Thanks for the explanation! I'll look into it.

@linusborg I agree with removing trailing slashes before comparison.

I don't quite get what OP wants... What's wrong with adding exact on roter-link?

@fnlctrl i want my <router-link to="/home" exact>/home</router-link> to be active for both /home and /home/ which doesn't work atm. This would be solved by @LinusBorg's proposal...

@jwahdatehagh Understood. I'll submit a PR shortly.

@LinusBorg @jwahdatehagh
The PR is submitted: https://github.com/vuejs/vue-router/pull/632/files

Had some troubles running flow on windows, and found that vue-router uses 0.29 while 0.31 is required for windows support. Tried running tests on 0.31 and everything passed, should probably submit a PR to update flow later. Totally forgot that I was on next-doc branch, which wasn't updated. Though it appears tests didn't break.

We should add a test for this case as well.

Yep.. adding one now.

Nice, thank you so much!

@jwahdatehagh
The PR's merged, should land in the next rc soon, so I'm closing this. :smile:

Thanks a log @fnlctrl

Was this page helpful?
0 / 5 - 0 ratings