perf: improve inject performance
This commit is contained in:
parent
0952d4cf51
commit
117630fb92
@ -7,24 +7,29 @@ export function provide<T>(key: Key<T>, value: T | Value<T>) {
|
||||
if (!currentInstance) {
|
||||
// TODO warn
|
||||
} else {
|
||||
const provides = currentInstance.provides || (currentInstance.provides = {})
|
||||
let provides = currentInstance.provides
|
||||
// by default an instance inherits its parent's provides object
|
||||
// but when it needs to provide values of its own, it creates its
|
||||
// own provides object using parent provides object as prototype.
|
||||
// this way in `inject` we can simply look up injections from direct
|
||||
// parent and let the prototype chain do the work.
|
||||
const parentProvides =
|
||||
currentInstance.parent && currentInstance.parent.provides
|
||||
if (parentProvides === provides) {
|
||||
provides = currentInstance.provides = Object.create(parentProvides)
|
||||
}
|
||||
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
|
||||
const provides = currentInstance.parent && currentInstance.provides
|
||||
if (provides) {
|
||||
const val = provides[key as any]
|
||||
return isValue(val) ? val : value(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ export type ComponentInstance<P = Data, S = Data> = {
|
||||
update: ReactiveEffect
|
||||
render: RenderFunction<P, S> | null
|
||||
effects: ReactiveEffect[] | null
|
||||
provides: Data | null
|
||||
provides: Data
|
||||
|
||||
// the rest are only for stateful components
|
||||
data: S
|
||||
@ -194,7 +194,7 @@ export function createComponentInstance(
|
||||
rtc: null,
|
||||
ec: null,
|
||||
effects: null,
|
||||
provides: null,
|
||||
provides: parent ? parent.provides : {},
|
||||
|
||||
// public properties
|
||||
data: EMPTY_OBJ,
|
||||
@ -225,7 +225,6 @@ export function setupStatefulComponent(instance: ComponentInstance) {
|
||||
// 2. call setup()
|
||||
const { setup } = Component
|
||||
if (setup) {
|
||||
currentInstance = instance
|
||||
// the props proxy makes the props object passed to setup() reactive
|
||||
// so props change can be tracked by watchers
|
||||
// it will be updated in resolveProps() on updates before render
|
||||
@ -234,7 +233,11 @@ export function setupStatefulComponent(instance: ComponentInstance) {
|
||||
: null)
|
||||
const setupContext = (instance.setupContext =
|
||||
setup.length > 1 ? createSetupContext(instance) : null)
|
||||
|
||||
currentInstance = instance
|
||||
const setupResult = setup.call(null, propsProxy, setupContext)
|
||||
currentInstance = null
|
||||
|
||||
if (isFunction(setupResult)) {
|
||||
// setup returned an inline render function
|
||||
instance.render = setupResult
|
||||
@ -247,7 +250,6 @@ export function setupStatefulComponent(instance: ComponentInstance) {
|
||||
}
|
||||
instance.render = Component.render as RenderFunction
|
||||
}
|
||||
currentInstance = null
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user