]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
perf: skip initializer extraction for options objects
authorEvan You <yyx990803@gmail.com>
Fri, 26 Oct 2018 16:11:52 +0000 (12:11 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 26 Oct 2018 16:11:52 +0000 (12:11 -0400)
packages/core/src/componentOptions.ts
packages/core/src/componentState.ts
packages/core/src/componentUtils.ts
packages/core/src/optional/mixins.ts

index ff3545f2ba1f93fc211b9d31a9a72b4b61ef7729..77fbb5158309abb79d778a5282526d52c4b51f5d 100644 (file)
@@ -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))
+  }
+}
index 9a04b02ef9353ebc57f3777a3c46e03f282da1d3..8d838dbe1f65a4578235befdc113e8ed54286a0a 100644 (file)
@@ -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 || {})
 }
 
index cad9bb75fc567f2eb5f429d32811de01e22f431c..54154a3c7a3831b6518c1f4eb8ddfce26093fdd3 100644 (file)
@@ -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) {
index cf2b2c09b54dfc37ffe69ba340d5656436017ad0..35fe31ea18fde67f5af5087c2a78405625935e07 100644 (file)
@@ -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)
     }