perf: skip initializer extraction for options objects
This commit is contained in:
		
							parent
							
								
									8db26a504c
								
							
						
					
					
						commit
						f142c322e0
					
				| @ -15,13 +15,17 @@ export interface ComponentClassOptions<P = {}, This = ComponentInstance> { | ||||
|   computed?: ComponentComputedOptions<This> | ||||
|   watch?: ComponentWatchOptions<This> | ||||
|   displayName?: string | ||||
|   fromOptions?: boolean | ||||
| } | ||||
| 
 | ||||
| export interface ComponentOptions< | ||||
|   P = {}, | ||||
|   D = {}, | ||||
|   This = ComponentInstance<P, D> | ||||
| > extends ComponentClassOptions<P, This>, APIMethods<P, D>, LifecycleMethods { | ||||
| > | ||||
|   extends ComponentClassOptions<P, This>, | ||||
|     Partial<APIMethods<P, D>>, | ||||
|     Partial<LifecycleMethods> { | ||||
|   // TODO other options
 | ||||
|   readonly [key: string]: any | ||||
| } | ||||
| @ -161,10 +165,7 @@ export function mergeComponentOptions(to: any, from: any): ComponentOptions { | ||||
|     if (isFunction(value) && isFunction(existing)) { | ||||
|       if (key === 'data') { | ||||
|         // for data we need to merge the returned value
 | ||||
|         // TODO: backwards compat requires recursive merge
 | ||||
|         res[key] = function() { | ||||
|           return Object.assign(existing.call(this), value.call(this)) | ||||
|         } | ||||
|         res[key] = mergeDataFn(existing, value) | ||||
|       } else if (/^render|^errorCaptured/.test(key)) { | ||||
|         // render, renderTracked, renderTriggered & errorCaptured
 | ||||
|         // are never merged
 | ||||
| @ -186,3 +187,11 @@ export function mergeComponentOptions(to: any, from: any): ComponentOptions { | ||||
|   } | ||||
|   return res | ||||
| } | ||||
| 
 | ||||
| export function mergeDataFn(a: Function, b: Function): Function { | ||||
|   // TODO: backwards compat requires recursive merge,
 | ||||
|   // but maybe we should just warn if we detect clashing keys
 | ||||
|   return function() { | ||||
|     return Object.assign(a.call(this), b.call(this)) | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -2,10 +2,15 @@ import { ComponentInstance } from './component' | ||||
| import { observable } from '@vue/observer' | ||||
| import { isReservedKey } from '@vue/shared' | ||||
| 
 | ||||
| export function initializeState(instance: ComponentInstance) { | ||||
| export function initializeState( | ||||
|   instance: ComponentInstance, | ||||
|   shouldExtractInitializers: boolean | ||||
| ) { | ||||
|   const { data } = instance.$options | ||||
|   const rawData = (instance._rawData = (data ? data.call(instance) : {}) as any) | ||||
|   extractInitializers(instance, rawData) | ||||
|   if (shouldExtractInitializers) { | ||||
|     extractInitializers(instance, rawData) | ||||
|   } | ||||
|   instance.$data = observable(rawData || {}) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -45,7 +45,7 @@ export function createComponentInstance<T extends Component>( | ||||
|     $proxy, | ||||
|     $options: { created, computed, watch } | ||||
|   } = instance | ||||
|   initializeState(instance) | ||||
|   initializeState(instance, !Component.fromOptions) | ||||
|   initializeComputed(instance, computed) | ||||
|   initializeWatch(instance, watch) | ||||
|   instance.$slots = currentVNode.slots || EMPTY_OBJ | ||||
| @ -104,7 +104,7 @@ export function initializeComponentInstance(instance: ComponentInstance) { | ||||
| export function renderInstanceRoot(instance: ComponentInstance): VNode { | ||||
|   let vnode | ||||
|   try { | ||||
|     vnode = instance.$options.render.call( | ||||
|     vnode = instance.render.call( | ||||
|       instance.$proxy, | ||||
|       instance.$props, | ||||
|       instance.$slots, | ||||
| @ -209,6 +209,8 @@ export function createComponentClassFromOptions( | ||||
| ): ComponentClass { | ||||
|   class AnonymousComponent extends Component { | ||||
|     static options = options | ||||
|     // indicate this component was created from options
 | ||||
|     static fromOptions = true | ||||
|   } | ||||
|   const proto = AnonymousComponent.prototype as any | ||||
|   for (const key in options) { | ||||
|  | ||||
| @ -3,7 +3,8 @@ import { createComponentClassFromOptions } from '../componentUtils' | ||||
| import { | ||||
|   ComponentOptions, | ||||
|   resolveComponentOptionsFromClass, | ||||
|   mergeComponentOptions | ||||
|   mergeComponentOptions, | ||||
|   mergeDataFn | ||||
| } from '../componentOptions' | ||||
| import { normalizePropsOptions } from '../componentProps' | ||||
| import { extractInitializers } from '../componentState' | ||||
| @ -47,11 +48,7 @@ export function mixins(...args: any[]): any { | ||||
|         return extractInitializers(new Class(this.$props)) | ||||
|       } | ||||
|       const { data } = mixin | ||||
|       mixin.data = data | ||||
|         ? function() { | ||||
|             return Object.assign(data.call(this), extractData.call(this)) | ||||
|           } | ||||
|         : extractData | ||||
|       mixin.data = data ? mergeDataFn(data, extractData) : extractData | ||||
|     } else { | ||||
|       mixin.props = normalizePropsOptions(mixin.props) | ||||
|     } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user