]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: reduce work in options -> class conversion
authorEvan You <yyx990803@gmail.com>
Fri, 26 Oct 2018 15:47:04 +0000 (11:47 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 26 Oct 2018 15:47:04 +0000 (11:47 -0400)
packages/core/src/componentOptions.ts
packages/core/src/componentUtils.ts

index e03cb3e7c8e18f088c9344ab5d9ad954e7b2a7b3..ff3545f2ba1f93fc211b9d31a9a72b4b61ef7729 100644 (file)
@@ -5,7 +5,6 @@ import {
   APIMethods,
   LifecycleMethods
 } from './component'
-import { Slots } from './vdom'
 import { isArray, isObject, isFunction } from '@vue/shared'
 import { normalizePropsOptions } from './componentProps'
 
@@ -22,9 +21,7 @@ export interface ComponentOptions<
   P = {},
   D = {},
   This = ComponentInstance<P, D>
-> extends ComponentClassOptions<P, This> {
-  data?(): D
-  render?: (this: This, props: Readonly<Data>, slots: Slots, attrs: Data) => any
+> extends ComponentClassOptions<P, This>, APIMethods<P, D>, LifecycleMethods {
   // TODO other options
   readonly [key: string]: any
 }
@@ -164,6 +161,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))
         }
index d31405812d6fbcb21ee7ac7ba3cc4daa35608eb0..cad9bb75fc567f2eb5f429d32811de01e22f431c 100644 (file)
@@ -1,5 +1,5 @@
 import { VNodeFlags } from './flags'
-import { EMPTY_OBJ, isArray, isFunction, isObject } from '@vue/shared'
+import { EMPTY_OBJ, isArray, isObject } from '@vue/shared'
 import { h } from './h'
 import { VNode, MountedVNode, createFragment } from './vdom'
 import {
@@ -104,7 +104,7 @@ export function initializeComponentInstance(instance: ComponentInstance) {
 export function renderInstanceRoot(instance: ComponentInstance): VNode {
   let vnode
   try {
-    vnode = instance.render.call(
+    vnode = instance.$options.render.call(
       instance.$proxy,
       instance.$props,
       instance.$slots,
@@ -213,35 +213,26 @@ export function createComponentClassFromOptions(
   const proto = AnonymousComponent.prototype as any
   for (const key in options) {
     const value = options[key]
-    // name -> displayName
-    if (key === 'name') {
-      options.displayName = options.name
-    } else if (isFunction(value)) {
-      // lifecycle hook / data / render
+    if (key === 'render') {
       if (__COMPAT__) {
-        if (key === 'render') {
-          proto[key] = function() {
-            return value.call(this, h)
-          }
-        } else if (key === 'beforeDestroy') {
-          proto.beforeUnmount = value
-        } else if (key === 'destroyed') {
-          proto.unmounted = value
-        } else {
-          proto[key] = value
+        options.render = function() {
+          return value.call(this, h)
         }
-      } else {
-        proto[key] = value
       }
+      // so that we can call instance.render directly
+      proto.render = options.render
     } else if (key === 'computed') {
+      // create computed setters on prototype
+      // (getters are handled by the render proxy)
       for (const computedKey in value) {
         const computed = value[computedKey]
-        const isGet = isFunction(computed)
-        Object.defineProperty(proto, computedKey, {
-          configurable: true,
-          get: isGet ? computed : computed.get,
-          set: isGet ? undefined : computed.set
-        })
+        const set = isObject(computed) && computed.set
+        if (set) {
+          Object.defineProperty(proto, computedKey, {
+            configurable: true,
+            set
+          })
+        }
       }
     } else if (key === 'methods') {
       for (const method in value) {
@@ -253,6 +244,18 @@ export function createComponentClassFromOptions(
         }
         proto[method] = value[method]
       }
+    } else if (__COMPAT__) {
+      if (key === 'name') {
+        options.displayName = value
+      } else if (key === 'render') {
+        options.render = function() {
+          return value.call(this, h)
+        }
+      } else if (key === 'beforeDestroy') {
+        options.beforeUnmount = value
+      } else if (key === 'destroyed') {
+        options.unmounted = value
+      }
     }
   }
   return AnonymousComponent as ComponentClass