diff --git a/packages/router/__tests__/matcher/resolve.spec.ts b/packages/router/__tests__/matcher/resolve.spec.ts index 359a3daa9..de00849e1 100644 --- a/packages/router/__tests__/matcher/resolve.spec.ts +++ b/packages/router/__tests__/matcher/resolve.spec.ts @@ -777,6 +777,40 @@ describe('RouterMatcher.resolve', () => { ) }) + it('keep optional params from parent record', () => { + const Child_A = { path: 'a', name: 'child_a', components } + const Child_B = { path: 'b', name: 'child_b', components } + const Parent = { + path: '/:optional?/parent', + name: 'parent', + components, + children: [Child_A, Child_B], + } + assertRecordMatch( + Parent, + { name: 'child_b' }, + { + name: 'child_b', + path: '/foo/parent/b', + params: { optional: 'foo' }, + matched: [ + Parent as any, + { + ...Child_B, + path: `${Parent.path}/${Child_B.path}`, + }, + ], + }, + { + params: { optional: 'foo' }, + path: '/foo/parent/a', + matched: [], + meta: {}, + name: undefined, + } + ) + }) + it('discards non existent params', () => { assertRecordMatch( { path: '/', name: 'home', components }, diff --git a/packages/router/src/matcher/index.ts b/packages/router/src/matcher/index.ts index 6c9a35d35..34250867b 100644 --- a/packages/router/src/matcher/index.ts +++ b/packages/router/src/matcher/index.ts @@ -277,8 +277,13 @@ export function createRouterMatcher( paramsFromLocation( currentLocation.params, // only keep params that exist in the resolved location - // TODO: only keep optional params coming from a parent record - matcher.keys.filter(k => !k.optional).map(k => k.name) + // only keep optional params coming from a parent record + matcher.keys + .filter(k => !k.optional) + .concat( + matcher.parent ? matcher.parent.keys.filter(k => k.optional) : [] + ) + .map(k => k.name) ), // discard any existing params in the current location that do not exist here // #1497 this ensures better active/exact matching