Skip to content

useSyncRef

useSyncRef 基于 Vueuse 的 syncRef 进行封装,其主要作用就是创建一个双向同步的 ref 变量,也可以设置为只对某个方向进行(ltrrtl),支持在同步的时候进行自定义转换。

useSyncRef 无法满足使用时,应考虑直接使用 syncRef

基本用法

如果你也写过类似的代码:

js
const props = definedProps({
  value: {
    type: String,
    required: true,
  },
})

const localValue = ref(props.value)

watchEffect(() => {
  localValue.value = props.value
})

const onChangeValue = newValue => {
  localValue.value = newValue
}
const props = definedProps({
  value: {
    type: String,
    required: true,
  },
})

const localValue = ref(props.value)

watchEffect(() => {
  localValue.value = props.value
})

const onChangeValue = newValue => {
  localValue.value = newValue
}

使用 useSyncRef,你能够轻松地实现相同的功能。

diff
+ import { useSyncRef } from '@ifanrx/uni-mp'

const props = definedProps({
  value: {
    type: String,
    required: true
  }
})

- const localValue = ref(props.value)
-
- watchEffect(() => {
-   localValue.value = props.value
- })

+ const localValue = useSyncRef(() => props.value)

const onChangeValue = (newValue) => {
  localValue.value = newValue
}
+ import { useSyncRef } from '@ifanrx/uni-mp'

const props = definedProps({
  value: {
    type: String,
    required: true
  }
})

- const localValue = ref(props.value)
-
- watchEffect(() => {
-   localValue.value = props.value
- })

+ const localValue = useSyncRef(() => props.value)

const onChangeValue = (newValue) => {
  localValue.value = newValue
}

进阶用法

双向同步

useSyncRef 默认为双向同步,这意味着无论修改哪一边的值,都将自动同步到另一边:

js
const source = ref(1)
const target = useSyncRef(source)

source.value++
console.log(target.value) // 2

target.value++
console.log(source.value) // 3
const source = ref(1)
const target = useSyncRef(source)

source.value++
console.log(target.value) // 2

target.value++
console.log(source.value) // 3

WARNING

需要注意的是,仅当第一个参数是 ref 变量时,双向同步才会生效。

让我们看一个示例,当 source 是一个 getter 时,修改 target 是无法同步修改 source 的:

js
const source = ref(1)
const target = useSyncRef(() => source.value)

target.value++
console.log(source.value) // 1,没有同步,因为 source 并不是 ref 变量
const source = ref(1)
const target = useSyncRef(() => source.value)

target.value++
console.log(source.value) // 1,没有同步,因为 source 并不是 ref 变量

单向同步

此外,你还可以自定义同步的方向:

js
const source = ref(1)

const target = useSyncRef(source, {
  direction: 'ltr', // 左到右,候选值:both(双向)、ltr(左到右)、rtl(右到左)
})

source.value++
console.log(target.value) // 2,说明会同步

target.value++
console.log(source.value) // 2,说明不会同步
const source = ref(1)

const target = useSyncRef(source, {
  direction: 'ltr', // 左到右,候选值:both(双向)、ltr(左到右)、rtl(右到左)
})

source.value++
console.log(target.value) // 2,说明会同步

target.value++
console.log(source.value) // 2,说明不会同步

转换器

你也可以自定义同步时如何取值:

js
const source = ref(1)

const target = useSyncRef(source, {
  direction: 'ltr',
  transform: {
    ltr: v => v * 10,
  },
})

source.value++
console.log(target.value) // 20
const source = ref(1)

const target = useSyncRef(source, {
  direction: 'ltr',
  transform: {
    ltr: v => v * 10,
  },
})

source.value++
console.log(target.value) // 20

常见问题

与 useShareState 的区别

也许你觉得 useSyncRefuseShareState 非常相似,的确它们都用于同步两个变量,但它们在使用场景方面有很大的不同。useSyncRef 用于在组件内部同步变量,而 useShareState 则专注于跨组件情况,其核心是 Event Bus。

请确保理解并区分它们的概念和用途。

相关文档

useSyncRef - API