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