import { autorun } from './index'
import { Autorun, activeAutorunStack } from './autorun'
-export interface ComputedGetter {
- (): any
+export interface ComputedGetter<T = any> {
+ (): T
runner: Autorun
}
-export function computed(getter: Function, context?: any): ComputedGetter {
+export function computed<T, C = null>(
+ getter: (this: C, ctx: C) => T,
+ context?: C
+): ComputedGetter<T> {
let dirty: boolean = true
let value: any = undefined
const runner = autorun(() => getter.call(context, context), {
import { ComponentInstance } from './component'
import { ComponentComputedOptions } from './componentOptions'
+export type ComputedHandles = Record<string, ComputedGetter>
+
export function initializeComputed(
instance: ComponentInstance,
computedOptions: ComponentComputedOptions | undefined
if (!computedOptions) {
return
}
- const handles: Record<
- string,
- ComputedGetter
- > = (instance._computedGetters = {})
+ const handles: ComputedHandles = (instance._computedGetters = {})
const proxy = instance.$proxy
for (const key in computedOptions) {
const option = computedOptions[key]
} else if (key[0] !== '_') {
if (__DEV__ && isRendering && !(key in target)) {
warn(
- `property "${key}" was accessed during render but does not exist on instance.`
+ `property "${key}" was accessed during render but does not exist ` +
+ `on instance.`
)
}
const value = Reflect.get(target, key, receiver)
import { ComponentInstance, FunctionalComponent, Component } from '../component'
import { mergeLifecycleHooks, Data, WatchOptions } from '../componentOptions'
import { VNode, Slots } from '../vdom'
-import { observable, computed, stop, ComputedGetter } from '@vue/observer'
+import { observable, computed } from '@vue/observer'
import { setupWatcher } from '../componentWatch'
type RawEffect = () => (() => void) | void
}
export function useComputed<T>(getter: () => T): T {
- const computedRef = useRef()
- useUnmounted(() => {
- stop((computedRef.current as ComputedGetter).runner)
- })
+ ensureCurrentInstance()
+ const id = `__hooksComputed${++callIndex}`
+ const instance = currentInstance as ComponentInstance
+ const handles = instance._computedGetters || (instance._computedGetters = {})
if (isMounting) {
- computedRef.current = computed(getter)
+ handles[id] = computed(getter)
}
- return (computedRef.current as ComputedGetter)()
+ return handles[id]()
}
export function withHooks(render: FunctionalComponent): new () => Component {