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)
|
||||
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…
Reference in New Issue
Block a user