From: Eduardo San Martin Morote Date: Wed, 29 Apr 2020 15:27:21 +0000 (+0200) Subject: fix(link): make alias of empty child active X-Git-Tag: v4.0.0-alpha.8~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cfe5993332cc7dc94c5de2f2edb7f2e15c9b7049;p=thirdparty%2Fvuejs%2Frouter.git fix(link): make alias of empty child active --- diff --git a/__tests__/RouterLink.spec.ts b/__tests__/RouterLink.spec.ts index fb627e0d..caadb7dd 100644 --- a/__tests__/RouterLink.spec.ts +++ b/__tests__/RouterLink.spec.ts @@ -20,7 +20,9 @@ const records = { foo: {} as RouteRecordNormalized, parent: {} as RouteRecordNormalized, childEmpty: {} as RouteRecordNormalized, + childEmptyAlias: {} as RouteRecordNormalized, child: {} as RouteRecordNormalized, + childChild: {} as RouteRecordNormalized, parentAlias: {} as RouteRecordNormalized, childAlias: {} as RouteRecordNormalized, } @@ -31,6 +33,7 @@ records.parentAlias = { aliasOf: records.parent, } as RouteRecordNormalized records.childAlias = { aliasOf: records.child } as RouteRecordNormalized +records.childEmptyAlias.aliasOf = records.childEmpty type RouteLocationResolved = RouteLocationNormalized & { href: string } @@ -189,6 +192,21 @@ const locations = createLocations({ name: undefined, }, }, + childEmptyAlias: { + string: '/parent/alias', + normalized: { + fullPath: '/parent/alias', + href: '/parent/alias', + path: '/parent/alias', + params: {}, + meta: {}, + query: {}, + hash: '', + matched: [records.parent, records.childEmptyAlias], + redirectedFrom: undefined, + name: undefined, + }, + }, child: { string: '/parent/child', normalized: { @@ -204,6 +222,21 @@ const locations = createLocations({ name: undefined, }, }, + childChild: { + string: '/parent/child/child', + normalized: { + fullPath: '/parent/child/child', + href: '/parent/child/child', + path: '/parent/child/child', + params: {}, + meta: {}, + query: {}, + hash: '', + matched: [records.parent, records.child, records.childChild], + redirectedFrom: undefined, + name: undefined, + }, + }, childAsAbsolute: { string: '/absolute-child', normalized: { @@ -503,6 +536,42 @@ describe('RouterLink', () => { ) }) + it('alias of empty path child is active as if it was the parent when on adjacent child', async () => { + const { wrapper } = await factory( + locations.child.normalized, + { to: locations.childEmptyAlias.string }, + locations.childEmptyAlias.normalized + ) + expect(wrapper.find('a')!.className).toContain('router-link-active') + expect(wrapper.find('a')!.className).not.toContain( + 'router-link-exact-active' + ) + }) + + it('empty path child is active as if it was the parent when on adjacent nested child', async () => { + const { wrapper } = await factory( + locations.childChild.normalized, + { to: locations.childEmpty.string }, + locations.childEmpty.normalized + ) + expect(wrapper.find('a')!.className).toContain('router-link-active') + expect(wrapper.find('a')!.className).not.toContain( + 'router-link-exact-active' + ) + }) + + it('alias of empty path child is active as if it was the parent when on adjacent nested nested child', async () => { + const { wrapper } = await factory( + locations.childChild.normalized, + { to: locations.childEmptyAlias.string }, + locations.childEmptyAlias.normalized + ) + expect(wrapper.find('a')!.className).toContain('router-link-active') + expect(wrapper.find('a')!.className).not.toContain( + 'router-link-exact-active' + ) + }) + it('alias parent is active if the child is an absolute path', async () => { const { wrapper } = await factory( locations.childAsAbsolute.normalized, diff --git a/playground/App.vue b/playground/App.vue index 95bdf45c..aca3f94a 100644 --- a/playground/App.vue +++ b/playground/App.vue @@ -72,6 +72,9 @@
  • /children
  • +
  • + /children/alias +
  • /children (child named) /children/b
  • +
  • + /children/b/a2 +
  • +
  • + /children/b/b2 +
  • /nested
  • diff --git a/playground/router.ts b/playground/router.ts index d1ba49e3..8c520fd1 100644 --- a/playground/router.ts +++ b/playground/router.ts @@ -62,9 +62,18 @@ export const router = createRouter({ name: 'WithChildren', component, children: [ - { path: '', name: 'default-child', component }, + { path: '', alias: 'alias', name: 'default-child', component }, { path: 'a', name: 'a-child', component }, - { path: 'b', name: 'b-child', component }, + { + path: 'b', + name: 'b-child', + component, + children: [ + { path: '', component }, + { path: 'a2', component }, + { path: 'b2', component }, + ], + }, ], }, { path: '/with-data', component: ComponentWithData, name: 'WithData' }, diff --git a/src/RouterLink.ts b/src/RouterLink.ts index 21829e28..189c93a2 100644 --- a/src/RouterLink.ts +++ b/src/RouterLink.ts @@ -40,19 +40,22 @@ export function useLink(props: UseLinkOptions) { ) if (index > -1) return index // possible parent record - let parentRecord = matched[length - 2] - if ( + let parentRecordPath = getOriginalPath( + matched[length - 2] as RouteRecord | undefined + ) + return ( + // we are dealing with nested routes length > 1 && - // if the have the same path, this link is referring to the empty child - // are we currently are on a different child of the same parent - routeMatched.path === parentRecord.path && - // avoid comparing the child with its parent - currentMatched[currentMatched.length - 1].path !== parentRecord.path + // if the have the same path, this link is referring to the empty child + // are we currently are on a different child of the same parent + getOriginalPath(routeMatched) === parentRecordPath && + // avoid comparing the child with its parent + currentMatched[currentMatched.length - 1].path !== parentRecordPath + ? currentMatched.findIndex( + isSameRouteRecord.bind(null, matched[length - 2]) + ) + : index ) - return currentMatched.findIndex( - isSameRouteRecord.bind(null, matched[length - 2]) - ) - return index }) const isActive = computed( @@ -168,3 +171,11 @@ function includesParams( return true } + +/** + * Get the original path value of a record by following its aliasOf + * @param record + */ +function getOriginalPath(record: RouteRecord | undefined): string { + return record ? (record.aliasOf ? record.aliasOf.path : record.path) : '' +}