]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(reactivity): store value cache on CustomRefs impls (#11539)
authorAlex <49969959+alexzhang1030@users.noreply.github.com>
Wed, 7 Aug 2024 14:24:28 +0000 (22:24 +0800)
committerGitHub <noreply@github.com>
Wed, 7 Aug 2024 14:24:28 +0000 (22:24 +0800)
Co-authored-by: Evan You <evan@vuejs.org>
packages/reactivity/__tests__/ref.spec.ts
packages/reactivity/src/ref.ts

index a3f56ab05c26b137c9a7352bdd2396b4da14a62a..0158ca0f64ace06e61c716babd6426156b61cb7a 100644 (file)
@@ -478,4 +478,38 @@ describe('reactivity/ref', () => {
     expect(toValue(c)).toBe(3)
     expect(toValue(d)).toBe(4)
   })
+
+  test('ref w/ customRef w/ getterRef w/ objectRef should store value cache', () => {
+    const refValue = ref(1)
+    // @ts-expect-error private field
+    expect(refValue._value).toBe(1)
+
+    let customRefValueCache = 0
+    const customRefValue = customRef((track, trigger) => {
+      return {
+        get() {
+          track()
+          return customRefValueCache
+        },
+        set(value: number) {
+          customRefValueCache = value
+          trigger()
+        },
+      }
+    })
+    customRefValue.value
+
+    // @ts-expect-error internal field
+    expect(customRefValue._value).toBe(0)
+
+    const getterRefValue = toRef(() => 1)
+    getterRefValue.value
+    // @ts-expect-error internal field
+    expect(getterRefValue._value).toBe(1)
+
+    const objectRefValue = toRef({ value: 1 }, 'value')
+    objectRefValue.value
+    // @ts-expect-error internal field
+    expect(objectRefValue._value).toBe(1)
+  })
 })
index 87b613e5773e58de09dbd747b522b059d285e1dc..34f9965fd9ef347df83102b2e62577b232cbd73a 100644 (file)
@@ -287,6 +287,8 @@ class CustomRefImpl<T> {
 
   public readonly [ReactiveFlags.IS_REF] = true
 
+  public _value: T = undefined!
+
   constructor(factory: CustomRefFactory<T>) {
     const dep = (this.dep = new Dep())
     const { get, set } = factory(dep.track.bind(dep), dep.trigger.bind(dep))
@@ -295,7 +297,7 @@ class CustomRefImpl<T> {
   }
 
   get value() {
-    return this._get()
+    return (this._value = this._get())
   }
 
   set value(newVal) {
@@ -339,6 +341,7 @@ export function toRefs<T extends object>(object: T): ToRefs<T> {
 
 class ObjectRefImpl<T extends object, K extends keyof T> {
   public readonly [ReactiveFlags.IS_REF] = true
+  public _value: T[K] = undefined!
 
   constructor(
     private readonly _object: T,
@@ -348,7 +351,7 @@ class ObjectRefImpl<T extends object, K extends keyof T> {
 
   get value() {
     const val = this._object[this._key]
-    return val === undefined ? this._defaultValue! : val
+    return (this._value = val === undefined ? this._defaultValue! : val)
   }
 
   set value(newVal) {
@@ -363,9 +366,11 @@ class ObjectRefImpl<T extends object, K extends keyof T> {
 class GetterRefImpl<T> {
   public readonly [ReactiveFlags.IS_REF] = true
   public readonly [ReactiveFlags.IS_READONLY] = true
+  public _value: T = undefined!
+
   constructor(private readonly _getter: () => T) {}
   get value() {
-    return this._getter()
+    return (this._value = this._getter())
   }
 }