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
|
|
|
|
}
|
|
|
|
}
|
2018-09-26 01:49:09 +08:00
|
|
|
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) {
|
2018-10-02 04:42:53 +08:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|