Skip to content

Commit bc9665d

Browse files
chaii3antfu
andauthored
fix(syncRef): avoid infinite sync (#3312)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
1 parent 3420640 commit bc9665d

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

packages/shared/syncRef/index.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,26 @@ describe('syncRef', () => {
5151

5252
it('works with mutual convertors', () => {
5353
const left = ref(10)
54-
const right = ref(1)
54+
const right = ref(2)
5555

5656
syncRef(left, right, {
5757
transform: {
5858
ltr: left => left * 2,
59-
rtl: right => Math.round(right / 2),
59+
rtl: right => Math.floor(right / 3),
6060
},
6161
})
6262

6363
// check immediately sync
6464
expect(right.value).toBe(20)
65-
expect(left.value).toBe(10)
65+
expect(left.value).toBe(6)
6666

6767
left.value = 30
6868
expect(right.value).toBe(60)
6969
expect(left.value).toBe(30)
7070

7171
right.value = 10
7272
expect(right.value).toBe(10)
73-
expect(left.value).toBe(5)
73+
expect(left.value).toBe(3)
7474
})
7575

7676
it('works with only rtl convertor', () => {

packages/shared/syncRef/index.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import type { Ref, WatchStopHandle } from 'vue-demi'
2-
import { watch } from 'vue-demi'
1+
import type { Ref } from 'vue-demi'
32
import type { ConfigurableFlushSync } from '../utils'
3+
import type { WatchPausableReturn } from '../watchPausable'
4+
import { pausableWatch } from '../watchPausable'
45

56
export interface SyncRefOptions<L, R = L> extends ConfigurableFlushSync {
67
/**
@@ -47,30 +48,38 @@ export function syncRef<L, R = L>(left: Ref<L>, right: Ref<R>, options: SyncRefO
4748
transform = {},
4849
} = options
4950

50-
let watchLeft: WatchStopHandle
51-
let watchRight: WatchStopHandle
51+
const watchers: WatchPausableReturn[] = []
5252

5353
const transformLTR = transform.ltr ?? (v => v)
5454
const transformRTL = transform.rtl ?? (v => v)
5555

5656
if (direction === 'both' || direction === 'ltr') {
57-
watchLeft = watch(
57+
watchers.push(pausableWatch(
5858
left,
59-
newValue => right.value = transformLTR(newValue) as R,
59+
(newValue) => {
60+
watchers.forEach(w => w.pause())
61+
right.value = transformLTR(newValue) as R
62+
watchers.forEach(w => w.resume())
63+
},
6064
{ flush, deep, immediate },
61-
)
65+
))
6266
}
6367

6468
if (direction === 'both' || direction === 'rtl') {
65-
watchRight = watch(
69+
watchers.push(pausableWatch(
6670
right,
67-
newValue => left.value = transformRTL(newValue) as L,
71+
(newValue) => {
72+
watchers.forEach(w => w.pause())
73+
left.value = transformRTL(newValue) as L
74+
watchers.forEach(w => w.resume())
75+
},
6876
{ flush, deep, immediate },
69-
)
77+
))
7078
}
7179

72-
return () => {
73-
watchLeft?.()
74-
watchRight?.()
80+
const stop = () => {
81+
watchers.forEach(w => w.stop())
7582
}
83+
84+
return stop
7685
}

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