From: pikax Date: Sun, 3 May 2020 21:29:54 +0000 (+0200) Subject: feat: allow numbers as params X-Git-Tag: v4.0.0-alpha.10~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef0920a86574bca10836214015c2317ed11a29b7;p=thirdparty%2Fvuejs%2Frouter.git feat: allow numbers as params Close #206 Co-authored-by: Eduardo San Martin Morote --- diff --git a/__tests__/router.spec.ts b/__tests__/router.spec.ts index 1d6c2a8c..7100673a 100644 --- a/__tests__/router.spec.ts +++ b/__tests__/router.spec.ts @@ -254,6 +254,12 @@ describe('Router', () => { expect(spy).toHaveBeenCalledTimes(1) }) + it('casts number params to string', async () => { + const { router } = await newRouter() + await router.push({ name: 'Param', params: { p: 0 } }) + expect(router.currentRoute.value).toMatchObject({ params: { p: '0' } }) + }) + it('navigates to same route record but different query', async () => { const { router } = await newRouter() await router.push('/?q=1') diff --git a/src/encoding.ts b/src/encoding.ts index c863c25e..260b6c37 100644 --- a/src/encoding.ts +++ b/src/encoding.ts @@ -84,7 +84,7 @@ export function encodeQueryProperty(text: string | number): string { * @param text - string to encode * @returns encoded string */ -export function encodePath(text: string): string { +export function encodePath(text: string | number): string { return commonEncode(text).replace(HASH_RE, '%23').replace(IM_RE, '%3F') } @@ -96,7 +96,7 @@ export function encodePath(text: string): string { * @param text - string to encode * @returns encoded string */ -export function encodeParam(text: string): string { +export function encodeParam(text: string | number): string { return encodePath(text).replace(SLASH_RE, '%2F') } @@ -107,11 +107,11 @@ export function encodeParam(text: string): string { * @param text - string to decode * @returns decoded string */ -export function decode(text: string): string { +export function decode(text: string | number): string { try { - return decodeURIComponent(text) + return decodeURIComponent('' + text) } catch (err) { __DEV__ && warn(`Error decoding "${text}". Using original value`) } - return text + return '' + text } diff --git a/src/router.ts b/src/router.ts index acefaa3d..e02bf3e2 100644 --- a/src/router.ts +++ b/src/router.ts @@ -5,13 +5,13 @@ import { PostNavigationGuard, START_LOCATION_NORMALIZED, Lazy, - MatcherLocation, RouteLocationNormalizedLoaded, RouteLocation, RouteRecordName, isRouteName, NavigationGuardWithThis, RouteLocationOptions, + MatcherLocationRaw, } from './types' import { RouterHistory, HistoryState } from './history/common' import { @@ -180,6 +180,10 @@ export function createRouter(options: RouterOptions): Router { history.scrollRestoration = 'manual' } + const normalizeParams = applyToParams.bind( + null, + paramValue => '' + paramValue + ) const encodeParams = applyToParams.bind(null, encodeParam) const decodeParams = applyToParams.bind(null, decode) @@ -249,6 +253,8 @@ export function createRouter(options: RouterOptions): Router { } } + let matcherLocation: MatcherLocationRaw + // path could be relative in object as well if ('path' in rawLocation) { if ( @@ -263,28 +269,25 @@ export function createRouter(options: RouterOptions): Router { }" was passed with params but they will be ignored. Use a named route alongside params instead.` ) } - rawLocation = { + matcherLocation = { ...rawLocation, path: parseURL(parseQuery, rawLocation.path, currentLocation.path).path, } + } else { + matcherLocation = { + ...rawLocation, + params: encodeParams(rawLocation.params), + } } - let matchedRoute: MatcherLocation = // relative or named location, path is ignored - // for same reason TS thinks rawLocation.params can be undefined - matcher.resolve( - 'params' in rawLocation - ? { ...rawLocation, params: encodeParams(rawLocation.params) } - : rawLocation, - currentLocation - ) + let matchedRoute = matcher.resolve(matcherLocation, currentLocation) const hash = encodeHash(rawLocation.hash || '') // put back the unencoded params as given by the user (avoid the cost of decoding them) - // TODO: normalize params if we accept numbers as raw values matchedRoute.params = 'params' in rawLocation - ? rawLocation.params! + ? normalizeParams(rawLocation.params) : decodeParams(matchedRoute.params) const fullPath = stringifyURL(stringifyQuery, { diff --git a/src/types/index.ts b/src/types/index.ts index 64d1be2a..d15753d5 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -20,14 +20,12 @@ export type VueUseOptions = { export type TODO = any export type RouteParamValue = string -// TODO: should we allow more values like numbers and normalize them to strings? -// type RouteParamValueRaw = RouteParamValue | number +export type RouteParamValueRaw = RouteParamValue | number export type RouteParams = Record -export type RouteParamsRaw = RouteParams -// export type RouteParamsRaw = Record< -// string, -// RouteParamValueRaw | RouteParamValueRaw[] -// > +export type RouteParamsRaw = Record< + string, + RouteParamValueRaw | RouteParamValueRaw[] +> export interface RouteQueryAndHash { query?: LocationQueryRaw @@ -37,13 +35,22 @@ export interface LocationAsPath { path: string } +export interface LocationAsNameRaw { + name: RouteRecordName + params?: RouteParamsRaw +} + export interface LocationAsName { name: RouteRecordName + params?: RouteParams +} + +export interface LocationAsRelativeRaw { params?: RouteParamsRaw } export interface LocationAsRelative { - params?: RouteParamsRaw + params?: RouteParams } export interface RouteLocationOptions { @@ -67,8 +74,8 @@ export interface RouteLocationOptions { export type RouteLocationRaw = | string | (RouteQueryAndHash & LocationAsPath & RouteLocationOptions) - | (RouteQueryAndHash & LocationAsName & RouteLocationOptions) - | (RouteQueryAndHash & LocationAsRelative & RouteLocationOptions) + | (RouteQueryAndHash & LocationAsNameRaw & RouteLocationOptions) + | (RouteQueryAndHash & LocationAsRelativeRaw & RouteLocationOptions) export interface RouteLocationMatched extends RouteRecordNormalized { // components cannot be Lazy diff --git a/src/utils/index.ts b/src/utils/index.ts index 9b074d02..de75374b 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,4 @@ -import { RouteParams, RouteComponent } from '../types' +import { RouteParams, RouteComponent, RouteParamsRaw } from '../types' import { hasSymbol } from '../injectionSymbols' export * from './env' @@ -8,8 +8,8 @@ export function isESModule(obj: any): obj is { default: RouteComponent } { } export function applyToParams( - fn: (v: string) => string, - params: RouteParams | undefined + fn: (v: string | number) => string, + params: RouteParamsRaw | undefined ): RouteParams { const newParams: RouteParams = {}