Skip to content

Commit 65aa076

Browse files
Akryumantfu
andauthored
feat(router): transform get / set (#4326)
Co-authored-by: Anthony Fu <[email protected]> Co-authored-by: Anthony Fu <[email protected]>
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)