Skip to content

Commit

Permalink
feat(router): transform get / set (#4326)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <[email protected]>
Co-authored-by: Anthony Fu <[email protected]>
  • Loading branch information
3 people authored Nov 21, 2024
1 parent 1d5e978 commit 65aa076
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 7 deletions.
5 changes: 4 additions & 1 deletion packages/router/_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@ export interface ReactiveRouteOptionsWithTransform<V, R> extends ReactiveRouteOp
/**
* Function to transform data before return
*/
transform?: (val: V) => R
transform?: ((val: V) => R) | {
get: (value: V) => R
set: (value: R) => V
}
}
25 changes: 25 additions & 0 deletions packages/router/useRouteParams/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,31 @@ describe('useRouteParams', () => {
expect(id.value).toBe(1)
})

it('should handle transform get/set', async () => {
let route = getRoute({
serialized: '{"foo":"bar"}',
})
const router = { replace: (r: any) => route = r } as any

const object = useRouteParams('serialized', undefined, {
transform: {
get: (value: string) => JSON.parse(value),
set: (value: any) => JSON.stringify(value),
},
router,
route,
})

expect(object.value).toEqual({ foo: 'bar' })

object.value = { foo: 'baz' }

await nextTick()

expect(route.params.serialized).toBe('{"foo":"baz"}')
expect(object.value).toEqual({ foo: 'baz' })
})

it('should re-evaluate the value immediately', () => {
let route = getRoute()
const router = { replace: (r: any) => route = r } as any
Expand Down
11 changes: 8 additions & 3 deletions packages/router/useRouteParams/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ export function useRouteParams<
mode = 'replace',
route = useRoute(),
router = useRouter(),
transform = value => value as any as K,
transform,
} = options

const transformGet = transform && 'get' in transform ? transform.get : transform ?? ((value: T) => value as any as K)
const transformSet = transform && 'set' in transform ? transform.set : (value: K) => value as any as T

if (!_queue.has(router))
_queue.set(router, new Map())

Expand All @@ -56,9 +59,11 @@ export function useRouteParams<
get() {
track()

return transform(param !== undefined && param !== '' ? param : toValue(defaultValue))
return transformGet(param !== undefined && param !== '' ? param : toValue(defaultValue))
},
set(v) {
v = transformSet(v)

if (param === v)
return

Expand Down Expand Up @@ -92,7 +97,7 @@ export function useRouteParams<
watch(
() => route.params[name],
(v) => {
if (param === transform(v as T))
if (param === transformGet(v as T))
return

param = v
Expand Down
25 changes: 25 additions & 0 deletions packages/router/useRouteQuery/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,31 @@ describe('useRouteQuery', () => {
expect(tags.value).toEqual(['vite'])
})

it('should handle transform get/set', async () => {
let route = getRoute({
serialized: '{"foo":"bar"}',
})
const router = { replace: (r: any) => route = r } as any

const object = useRouteQuery('serialized', undefined, {
transform: {
get: (value: string) => JSON.parse(value),
set: (value: any) => JSON.stringify(value),
},
router,
route,
})

expect(object.value).toEqual({ foo: 'bar' })

object.value = { foo: 'baz' }

await nextTick()

expect(route.query.serialized).toBe('{"foo":"baz"}')
expect(object.value).toEqual({ foo: 'baz' })
})

it('should re-evaluate the value immediately', () => {
let route = getRoute({
search: 'vue3',
Expand Down
11 changes: 8 additions & 3 deletions packages/router/useRouteQuery/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ export function useRouteQuery<
mode = 'replace',
route = useRoute(),
router = useRouter(),
transform = value => value as any as K,
transform,
} = options

const transformGet = transform && 'get' in transform ? transform.get : transform ?? ((value: T) => value as any as K)
const transformSet = transform && 'set' in transform ? transform.set : (value: K) => value as any as T

if (!_queue.has(router))
_queue.set(router, new Map())

Expand All @@ -56,9 +59,11 @@ export function useRouteQuery<
get() {
track()

return transform(query !== undefined ? query : toValue(defaultValue))
return transformGet(query !== undefined ? query : toValue(defaultValue))
},
set(v) {
v = transformSet(v)

if (query === v)
return

Expand Down Expand Up @@ -89,7 +94,7 @@ export function useRouteQuery<
watch(
() => route.query[name],
(v) => {
if (query === transform(v as T))
if (query === transformGet(v as T))
return

query = v
Expand Down

0 comments on commit 65aa076

Please sign in to comment.