diff --git a/packages/router/__tests__/router.spec.ts b/packages/router/__tests__/router.spec.ts index 691b9d9f5..3d86e1743 100644 --- a/packages/router/__tests__/router.spec.ts +++ b/packages/router/__tests__/router.spec.ts @@ -534,6 +534,18 @@ describe('Router', () => { }) }) + // https://github.com/vuejs/router/issues/2187 + it('keeps a consistent value on fullPath when resolving', async () => { + const { router } = await newRouter() + const targetLoc = '/search#/?redirect=%2F%3Fid%3D1%23%2Fabc' + expect(router.resolve(targetLoc).fullPath).toBe(targetLoc) + await router.push(targetLoc) + expect(router.currentRoute.value.fullPath).toBe(targetLoc) + await router.push('/') + await router.replace(targetLoc) + expect(router.currentRoute.value.fullPath).toBe(targetLoc) + }) + describe('navigation cancelled', () => { async function checkNavigationCancelledOnPush( target?: RouteLocationRaw | false diff --git a/packages/router/src/router.ts b/packages/router/src/router.ts index 20ab4d1e2..dcf3369d6 100644 --- a/packages/router/src/router.ts +++ b/packages/router/src/router.ts @@ -525,13 +525,19 @@ export function createRouter(options: RouterOptions): Router { // we need to run the decoding again matchedRoute.params = normalizeParams(decodeParams(matchedRoute.params)) - const fullPath = stringifyURL( - stringifyQuery, - assign({}, rawLocation, { - hash: encodeHash(hash), - path: matchedRoute.path, - }) - ) + const fullPath = + // @ts-expect-error: the rawLocation doesn't normally have a fullPath + // but sometimes it gets noramlized before being passed to resolve and we can + // resue it to avoid encoding an unencoded path from the user in order to be closer + // to the URL constructor behavior. vuejs/router#2187 + rawLocation.fullPath || + stringifyURL( + stringifyQuery, + assign({}, rawLocation, { + hash: encodeHash(hash), + path: matchedRoute.path, + }) + ) const href = routerHistory.createHref(fullPath) if (__DEV__) {