{ path: '/to-p/:p', redirect: to => `/p/${to.params.p}` },
{ path: '/p/:p', component: components.Bar, name: 'params' },
{ path: '/p/:p+', component: components.Bar, name: 'repeat' },
+ { path: '/optional/:a/:b?', component: components.Bar, name: 'optional' },
]
function createRouter() {
const router = createRouter()
await router.push('/p/bar')
await router.push({ params: { p: 'foo' } })
- expect(encoding.encodeParam).toHaveBeenCalledTimes(1)
+ expect(encoding.encodeParam).toHaveBeenCalledTimes(2)
+ expect(encoding.encodeParam).toHaveBeenCalledWith('bar')
expect(encoding.encodeParam).toHaveBeenCalledWith('foo')
})
expect(encoding.decode).toHaveBeenNthCalledWith(2, 'bar', 1, ['foo', 'bar'])
})
- it('keeps decoded values in params', async () => {
+ it('decodes values in params', async () => {
// @ts-ignore: override to make the difference
encoding.decode = () => 'd'
// @ts-ignore
encoding.encodeParam = () => 'e'
const router = createRouter()
- await router.push({ name: 'params', params: { p: '%' } })
+ await router.push({ name: 'optional', params: { a: 'a%' } })
+ await router.push({ params: { b: 'b%' } })
expect(router.currentRoute.value).toMatchObject({
- fullPath: '/p/e',
- params: { p: '%' },
+ fullPath: '/optional/e/e',
+ params: { b: 'd', a: 'd' },
})
})
function resolve(
rawLocation: Readonly<RouteLocationRaw>,
- currentLocation?: Readonly<RouteLocationNormalizedLoaded>
+ currentLocation?: RouteLocationNormalizedLoaded
): RouteLocation & { href: string } {
// const objectLocation = routerLocationAsObject(rawLocation)
- currentLocation = currentLocation || currentRoute.value
+ // we create a copy to modify it later
+ currentLocation = { ...(currentLocation || currentRoute.value) }
if (typeof rawLocation === 'string') {
let locationNormalized = parseURL(
parseQuery,
path: parseURL(parseQuery, rawLocation.path, currentLocation.path).path,
})
} else {
+ // pass encoded values to the matcher so it can produce encoded path and fullPath
matcherLocation = assign({}, rawLocation, {
params: encodeParams(rawLocation.params),
})
+ // current location params are decoded, we need to encode them in case the
+ // matcher merges the params
+ currentLocation.params = encodeParams(currentLocation.params)
}
let matchedRoute = matcher.resolve(matcherLocation, currentLocation)
)
}
- // put back the unencoded params as given by the user (avoid the cost of decoding them)
- matchedRoute.params =
- 'params' in rawLocation
- ? normalizeParams(rawLocation.params)
- : decodeParams(matchedRoute.params)
+ // decoding them) the matcher might have merged current location params so
+ // we need to run the decoding again
+ matchedRoute.params = normalizeParams(decodeParams(matchedRoute.params))
const fullPath = stringifyURL(
stringifyQuery,