Explorar el Código

wip: provide/inject

Evan You hace 7 años
padre
commit
0952d4cf51

+ 30 - 0
packages/runtime-core/src/apiInject.ts

@@ -0,0 +1,30 @@
+import { value, isValue, Value } from './apiState'
+import { currentInstance } from './component'
+
+export interface Key<T> extends Symbol {}
+
+export function provide<T>(key: Key<T>, value: T | Value<T>) {
+  if (!currentInstance) {
+    // TODO warn
+  } else {
+    const provides = currentInstance.provides || (currentInstance.provides = {})
+    provides[key as any] = value
+  }
+}
+
+export function inject<T>(key: Key<T>): Value<T> | undefined {
+  // traverse parent chain and look for provided value
+  if (!currentInstance) {
+    // TODO warn
+  } else {
+    let parent = currentInstance.parent
+    while (parent) {
+      const { provides } = parent
+      if (provides !== null && provides.hasOwnProperty(key as any)) {
+        const val = provides[key as any]
+        return isValue(val) ? val : value(val)
+      }
+      parent = parent.parent
+    }
+  }
+}

+ 4 - 2
packages/runtime-core/src/component.ts

@@ -79,7 +79,7 @@ export interface FunctionalComponent<P = {}> {
 
 type LifecycleHook = Function[] | null
 
-interface LifecycleHooks {
+export interface LifecycleHooks {
   bm: LifecycleHook // beforeMount
   m: LifecycleHook // mounted
   bu: LifecycleHook // beforeUpdate
@@ -110,8 +110,9 @@ export type ComponentInstance<P = Data, S = Data> = {
   next: VNode | null
   subTree: VNode
   update: ReactiveEffect
-  effects: ReactiveEffect[] | null
   render: RenderFunction<P, S> | null
+  effects: ReactiveEffect[] | null
+  provides: Data | null
 
   // the rest are only for stateful components
   data: S
@@ -193,6 +194,7 @@ export function createComponentInstance(
     rtc: null,
     ec: null,
     effects: null,
+    provides: null,
 
     // public properties
     data: EMPTY_OBJ,

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

@@ -18,5 +18,6 @@ export { PropType, ComponentPropsOptions } from './componentProps'
 export * from './apiState'
 export * from './apiWatch'
 export * from './apiLifecycle'
+export * from './apiInject'
 export * from './patchFlags'
 export * from './typeFlags'