vue3-yuanma/packages/core/src/componentComputed.ts

71 lines
1.8 KiB
TypeScript
Raw Normal View History

2018-10-10 01:59:30 +08:00
import { EMPTY_OBJ, NOOP } from './utils'
2018-09-21 06:36:34 +08:00
import { computed, stop, ComputedGetter } from '@vue/observer'
2018-10-09 23:37:24 +08:00
import { ComponentClass, ComponentInstance } from './component'
2018-09-19 23:35:38 +08:00
import { ComponentComputedOptions } from './componentOptions'
const extractionCache: WeakMap<
ComponentClass,
ComponentComputedOptions
> = new WeakMap()
export function getComputedOptions(
comp: ComponentClass
): ComponentComputedOptions {
let computedOptions = extractionCache.get(comp)
if (computedOptions) {
return computedOptions
}
computedOptions = {}
const descriptors = Object.getOwnPropertyDescriptors(comp.prototype as any)
for (const key in descriptors) {
const d = descriptors[key]
if (d.get) {
computedOptions[key] = d.get
// there's no need to do anything for the setter
// as it's already defined on the prototype
}
}
extractionCache.set(comp, computedOptions)
2018-09-19 23:35:38 +08:00
return computedOptions
}
export function initializeComputed(
2018-10-09 23:37:24 +08:00
instance: ComponentInstance,
2018-09-19 23:35:38 +08:00
computedOptions: ComponentComputedOptions | undefined
) {
if (!computedOptions) {
instance.$computed = EMPTY_OBJ
return
}
const handles: Record<
string,
ComputedGetter
> = (instance._computedGetters = {})
const proxy = instance.$proxy
for (const key in computedOptions) {
2018-10-10 01:59:30 +08:00
const option = computedOptions[key]
const getter = typeof option === 'function' ? option : option.get || NOOP
handles[key] = computed(getter, proxy)
2018-09-19 23:35:38 +08:00
}
instance.$computed = new Proxy(
{},
{
get(_, key: any) {
if (handles.hasOwnProperty(key)) {
return handles[key]()
}
2018-09-19 23:35:38 +08:00
}
// TODO should be readonly
}
)
}
2018-10-09 23:37:24 +08:00
export function teardownComputed(instance: ComponentInstance) {
2018-09-19 23:35:38 +08:00
const handles = instance._computedGetters
if (handles !== null) {
for (const key in handles) {
2018-09-21 06:36:34 +08:00
stop(handles[key].runner)
2018-09-19 23:35:38 +08:00
}
}
}