refactor: use more efficient useComputed() implementation
This commit is contained in:
		
							parent
							
								
									f9e3e38fdb
								
							
						
					
					
						commit
						8602b61efb
					
				| @ -1,12 +1,15 @@ | ||||
| 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), { | ||||
|  | ||||
| @ -3,6 +3,8 @@ import { computed, stop, ComputedGetter } from '@vue/observer' | ||||
| import { ComponentInstance } from './component' | ||||
| import { ComponentComputedOptions } from './componentOptions' | ||||
| 
 | ||||
| export type ComputedHandles = Record<string, ComputedGetter> | ||||
| 
 | ||||
| export function initializeComputed( | ||||
|   instance: ComponentInstance, | ||||
|   computedOptions: ComponentComputedOptions | undefined | ||||
| @ -10,10 +12,7 @@ export function initializeComputed( | ||||
|   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] | ||||
|  | ||||
| @ -43,7 +43,8 @@ const renderProxyHandlers = { | ||||
|     } 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) | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| 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 | ||||
| @ -191,14 +191,14 @@ export function useWatch<T>( | ||||
| } | ||||
| 
 | ||||
| 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 { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user