Skip to content

Commit 65aa076

Browse files
Akryumantfu
andauthored
feat(router): transform get / set (#4326)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com> Co-authored-by: Anthony Fu <github@antfu.me>
1 parent 1d5e978 commit 65aa076

File tree

5 files changed

+70
-7
lines changed

5 files changed

+70
-7
lines changed

packages/router/_types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@ export interface ReactiveRouteOptionsWithTransform<V, R> extends ReactiveRouteOp
2828
/**
2929
* Function to transform data before return
3030
*/
31-
transform?: (val: V) => R
31+
transform?: ((val: V) => R) | {
32+
get: (value: V) => R
33+
set: (value: R) => V
34+
}
3235
}

packages/router/useRouteParams/index.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,31 @@ describe('useRouteParams', () => {
4040
expect(id.value).toBe(1)
4141
})
4242

43+
it('should handle transform get/set', async () => {
44+
let route = getRoute({
45+
serialized: '{"foo":"bar"}',
46+
})
47+
const router = { replace: (r: any) => route = r } as any
48+
49+
const object = useRouteParams('serialized', undefined, {
50+
transform: {
51+
get: (value: string) => JSON.parse(value),
52+
set: (value: any) => JSON.stringify(value),
53+
},
54+
router,
55+
route,
56+
})
57+
58+
expect(object.value).toEqual({ foo: 'bar' })
59+
60+
object.value = { foo: 'baz' }
61+
62+
await nextTick()
63+
64+
expect(route.params.serialized).toBe('{"foo":"baz"}')
65+
expect(object.value).toEqual({ foo: 'baz' })
66+
})
67+
4368
it('should re-evaluate the value immediately', () => {
4469
let route = getRoute()
4570
const router = { replace: (r: any) => route = r } as any

packages/router/useRouteParams/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ export function useRouteParams<
3333
mode = 'replace',
3434
route = useRoute(),
3535
router = useRouter(),
36-
transform = value => value as any as K,
36+
transform,
3737
} = options
3838

39+
const transformGet = transform && 'get' in transform ? transform.get : transform ?? ((value: T) => value as any as K)
40+
const transformSet = transform && 'set' in transform ? transform.set : (value: K) => value as any as T
41+
3942
if (!_queue.has(router))
4043
_queue.set(router, new Map())
4144

@@ -56,9 +59,11 @@ export function useRouteParams<
5659
get() {
5760
track()
5861

59-
return transform(param !== undefined && param !== '' ? param : toValue(defaultValue))
62+
return transformGet(param !== undefined && param !== '' ? param : toValue(defaultValue))
6063
},
6164
set(v) {
65+
v = transformSet(v)
66+
6267
if (param === v)
6368
return
6469

@@ -92,7 +97,7 @@ export function useRouteParams<
9297
watch(
9398
() => route.params[name],
9499
(v) => {
95-
if (param === transform(v as T))
100+
if (param === transformGet(v as T))
96101
return
97102

98103
param = v

packages/router/useRouteQuery/index.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,31 @@ describe('useRouteQuery', () => {
3838
expect(tags.value).toEqual(['vite'])
3939
})
4040

41+
it('should handle transform get/set', async () => {
42+
let route = getRoute({
43+
serialized: '{"foo":"bar"}',
44+
})
45+
const router = { replace: (r: any) => route = r } as any
46+
47+
const object = useRouteQuery('serialized', undefined, {
48+
transform: {
49+
get: (value: string) => JSON.parse(value),
50+
set: (value: any) => JSON.stringify(value),
51+
},
52+
router,
53+
route,
54+
})
55+
56+
expect(object.value).toEqual({ foo: 'bar' })
57+
58+
object.value = { foo: 'baz' }
59+
60+
await nextTick()
61+
62+
expect(route.query.serialized).toBe('{"foo":"baz"}')
63+
expect(object.value).toEqual({ foo: 'baz' })
64+
})
65+
4166
it('should re-evaluate the value immediately', () => {
4267
let route = getRoute({
4368
search: 'vue3',

packages/router/useRouteQuery/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ export function useRouteQuery<
3333
mode = 'replace',
3434
route = useRoute(),
3535
router = useRouter(),
36-
transform = value => value as any as K,
36+
transform,
3737
} = options
3838

39+
const transformGet = transform && 'get' in transform ? transform.get : transform ?? ((value: T) => value as any as K)
40+
const transformSet = transform && 'set' in transform ? transform.set : (value: K) => value as any as T
41+
3942
if (!_queue.has(router))
4043
_queue.set(router, new Map())
4144

@@ -56,9 +59,11 @@ export function useRouteQuery<
5659
get() {
5760
track()
5861

59-
return transform(query !== undefined ? query : toValue(defaultValue))
62+
return transformGet(query !== undefined ? query : toValue(defaultValue))
6063
},
6164
set(v) {
65+
v = transformSet(v)
66+
6267
if (query === v)
6368
return
6469

@@ -89,7 +94,7 @@ export function useRouteQuery<
8994
watch(
9095
() => route.query[name],
9196
(v) => {
92-
if (query === transform(v as T))
97+
if (query === transformGet(v as T))
9398
return
9499

95100
query = v

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy