Ver Fonte

feat: toRefs

Evan You há 6 anos atrás
pai
commit
b218678c66

+ 2 - 2
packages/reactivity/src/computed.ts

@@ -1,5 +1,5 @@
 import { effect, ReactiveEffect, activeReactiveEffectStack } from './effect'
-import { UnwrapNestedRefs, knownValues } from './ref'
+import { UnwrapNestedRefs, knownRefs } from './ref'
 
 export interface ComputedRef<T> {
   readonly value: UnwrapNestedRefs<T>
@@ -42,7 +42,7 @@ export function computed<T>(
       }
     }
   }
-  knownValues.add(computedValue)
+  knownRefs.add(computedValue)
   return computedValue
 }
 

+ 1 - 1
packages/reactivity/src/index.ts

@@ -1,4 +1,4 @@
-export { ref, isRef, Ref, UnwrapRef } from './ref'
+export { ref, isRef, toRefs, Ref, UnwrapRef } from './ref'
 export {
   reactive,
   isReactive,

+ 30 - 4
packages/reactivity/src/ref.ts

@@ -3,7 +3,7 @@ import { OperationTypes } from './operations'
 import { isObject } from '@vue/shared'
 import { reactive } from './reactive'
 
-export const knownValues = new WeakSet()
+export const knownRefs = new WeakSet()
 
 export interface Ref<T> {
   value: UnwrapNestedRefs<T>
@@ -25,12 +25,38 @@ export function ref<T>(raw: T): Ref<T> {
       trigger(v, OperationTypes.SET, '')
     }
   }
-  knownValues.add(v)
-  return v as any
+  knownRefs.add(v)
+  return v as Ref<T>
 }
 
 export function isRef(v: any): v is Ref<any> {
-  return knownValues.has(v)
+  return knownRefs.has(v)
+}
+
+export function toRefs<T extends object>(
+  object: T
+): { [K in keyof T]: Ref<T[K]> } {
+  const ret: any = {}
+  for (const key in object) {
+    ret[key] = toProxyRef(object, key)
+  }
+  return ret
+}
+
+function toProxyRef<T extends object, K extends keyof T>(
+  object: T,
+  key: K
+): Ref<T[K]> {
+  const v = {
+    get value() {
+      return object[key]
+    },
+    set value(newVal) {
+      object[key] = newVal
+    }
+  }
+  knownRefs.add(v)
+  return v as Ref<T[K]>
 }
 
 type BailTypes =

+ 1 - 1
packages/runtime-core/src/apiInject.ts

@@ -1,5 +1,5 @@
 import { currentInstance } from './component'
-import { immutable } from './apiState'
+import { immutable } from './apiReactivity'
 import { isObject } from '@vue/shared'
 
 export interface InjectionKey<T> extends Symbol {}

+ 1 - 0
packages/runtime-core/src/apiState.ts → packages/runtime-core/src/apiReactivity.ts

@@ -1,6 +1,7 @@
 export {
   ref,
   isRef,
+  toRefs,
   reactive,
   isReactive,
   immutable,

+ 1 - 1
packages/runtime-core/src/apiWatch.ts

@@ -7,7 +7,7 @@ import {
 } from '@vue/reactivity'
 import { queueJob, queuePostFlushCb } from './scheduler'
 import { EMPTY_OBJ, isObject, isArray, isFunction } from '@vue/shared'
-import { recordEffect } from './apiState'
+import { recordEffect } from './apiReactivity'
 
 export interface WatchOptions {
   lazy?: boolean

+ 1 - 1
packages/runtime-core/src/index.ts

@@ -19,7 +19,7 @@ export { createRenderer, RendererOptions } from './createRenderer'
 export { Slot, Slots } from './componentSlots'
 export { PropType, ComponentPropsOptions } from './componentProps'
 
-export * from './apiState'
+export * from './apiReactivity'
 export * from './apiWatch'
 export * from './apiLifecycle'
 export * from './apiInject'