isReactive
} from '../src/index'
import { computed } from '@vue/runtime-dom'
-import { shallowRef, unref } from '../src/ref'
+import { shallowRef, unref, customRef } from '../src/ref'
describe('reactivity/ref', () => {
it('should hold a value', () => {
expect(dummyX).toBe(4)
expect(dummyY).toBe(5)
})
+
+ test('customRef', () => {
+ let value = 1
+ let _trigger: () => void
+
+ const custom = customRef((track, trigger) => ({
+ get() {
+ track()
+ return value
+ },
+ set(newValue: number) {
+ value = newValue
+ _trigger = trigger
+ }
+ }))
+
+ let dummy
+ effect(() => {
+ dummy = custom.value
+ })
+ expect(dummy).toBe(1)
+
+ custom.value = 2
+ // should not trigger yet
+ expect(dummy).toBe(1)
+
+ _trigger!()
+ expect(dummy).toBe(2)
+ })
})
-export { ref, unref, shallowRef, isRef, toRefs, Ref, UnwrapRef } from './ref'
+export {
+ ref,
+ unref,
+ shallowRef,
+ isRef,
+ toRefs,
+ customRef,
+ Ref,
+ UnwrapRef
+} from './ref'
export {
reactive,
isReactive,
return isRef(ref) ? (ref.value as any) : ref
}
+export type CustomRefFactory<T> = (
+ track: () => void,
+ trigger: () => void
+) => {
+ get: () => T
+ set: (value: T) => void
+}
+
+export function customRef<T>(factory: CustomRefFactory<T>): Ref<T> {
+ const { get, set } = factory(
+ () => track(r, TrackOpTypes.GET, 'value'),
+ () => trigger(r, TriggerOpTypes.SET, 'value')
+ )
+ const r = {
+ _isRef: true,
+ get value() {
+ return get()
+ },
+ set value(v) {
+ set(v)
+ }
+ }
+ return r as any
+}
+
export function toRefs<T extends object>(
object: T
): { [K in keyof T]: Ref<T[K]> } {
shallowRef,
isRef,
toRefs,
+ customRef,
reactive,
isReactive,
readonly,
isReadonly,
shallowReactive,
- toRaw,
- markNonReactive
+ markNonReactive,
+ toRaw
} from '@vue/reactivity'
export { computed } from './apiComputed'
export { watch, watchEffect } from './apiWatch'