From 76294db82905c9b1a84975e8b5f1cce41d3601ad Mon Sep 17 00:00:00 2001 From: Nikita Mikhailov Date: Mon, 14 Aug 2023 01:08:49 +0300 Subject: [PATCH] feat(syncRef): fix infinite sync --- packages/shared/syncRef/index.test.ts | 8 +++---- packages/shared/syncRef/index.ts | 30 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/packages/shared/syncRef/index.test.ts b/packages/shared/syncRef/index.test.ts index ad5d464f41e..b982630caed 100644 --- a/packages/shared/syncRef/index.test.ts +++ b/packages/shared/syncRef/index.test.ts @@ -51,18 +51,18 @@ describe('syncRef', () => { it('works with mutual convertors', () => { const left = ref(10) - const right = ref(1) + const right = ref(2) syncRef(left, right, { transform: { ltr: left => left * 2, - rtl: right => Math.round(right / 2), + rtl: right => Math.floor(right / 3), }, }) // check immediately sync expect(right.value).toBe(20) - expect(left.value).toBe(10) + expect(left.value).toBe(6) left.value = 30 expect(right.value).toBe(60) @@ -70,7 +70,7 @@ describe('syncRef', () => { right.value = 10 expect(right.value).toBe(10) - expect(left.value).toBe(5) + expect(left.value).toBe(3) }) it('works with only rtl convertor', () => { diff --git a/packages/shared/syncRef/index.ts b/packages/shared/syncRef/index.ts index 975c7126dde..629b41a5298 100644 --- a/packages/shared/syncRef/index.ts +++ b/packages/shared/syncRef/index.ts @@ -1,5 +1,6 @@ -import type { Ref, WatchStopHandle } from 'vue-demi' -import { watch } from 'vue-demi' +import { pausableWatch } from '@vueuse/core' +import type { WatchPausableReturn } from '@vueuse/core' +import type { Ref } from 'vue-demi' import type { ConfigurableFlushSync } from '../utils' export interface SyncRefOptions extends ConfigurableFlushSync { @@ -37,6 +38,7 @@ export interface SyncRefOptions extends ConfigurableFlushSync { * * @param left * @param right + * @param options */ export function syncRef(left: Ref, right: Ref, options: SyncRefOptions = {}) { const { @@ -47,30 +49,38 @@ export function syncRef(left: Ref, right: Ref, options: SyncRefO transform = {}, } = options - let watchLeft: WatchStopHandle - let watchRight: WatchStopHandle + let watchLeft: WatchPausableReturn + let watchRight: WatchPausableReturn const transformLTR = transform.ltr ?? (v => v) const transformRTL = transform.rtl ?? (v => v) if (direction === 'both' || direction === 'ltr') { - watchLeft = watch( + watchLeft = pausableWatch( left, - newValue => right.value = transformLTR(newValue) as R, + (newValue) => { + watchRight?.pause() + right.value = transformLTR(newValue) as R + watchRight?.resume() + }, { flush, deep, immediate }, ) } if (direction === 'both' || direction === 'rtl') { - watchRight = watch( + watchRight = pausableWatch( right, - newValue => left.value = transformRTL(newValue) as L, + (newValue) => { + watchLeft?.pause() + left.value = transformRTL(newValue) as L + watchLeft?.resume() + }, { flush, deep, immediate }, ) } return () => { - watchLeft?.() - watchRight?.() + watchLeft?.stop() + watchRight?.stop() } }