]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: access all options from instance.$options
authorEvan You <yyx990803@gmail.com>
Tue, 16 Oct 2018 16:37:31 +0000 (12:37 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 16 Oct 2018 16:37:31 +0000 (12:37 -0400)
packages/core/src/component.ts
packages/core/src/componentComputed.ts
packages/core/src/componentOptions.ts
packages/core/src/componentProps.ts
packages/core/src/componentProxy.ts
packages/core/src/componentUtils.ts

index 6d5d4bfa5ec64412f897877cefef4226f8384d77..ee62fd22137fbd9262a9b110497282bde322e963 100644 (file)
@@ -99,6 +99,7 @@ export interface ComponentInstance<P = {}, D = {}>
   $slots: Slots
   $root: ComponentInstance
   $children: ComponentInstance[]
+  $options: ComponentOptions<P, D>
 
   _updateHandle: Autorun
   _queueJob: ((fn: () => void) => void)
@@ -120,7 +121,7 @@ class InternalComponent implements PublicInstanceMethods {
   $root: ComponentInstance | null = null
   $parent: ComponentInstance | null = null
   $children: ComponentInstance[] = []
-  $options: ComponentOptions
+  $options: ComponentOptions | null = null
   $refs: Record<string, ComponentInstance | RenderNode> = {}
   $proxy: any = null
 
index fa44269530e443e0850d02cd428c9d025410f2a8..4f3e99c2bc259c358b50247b0d6eb5690e71b387 100644 (file)
@@ -1,24 +1,8 @@
 import { NOOP } from './utils'
 import { computed, stop, ComputedGetter } from '@vue/observer'
-import { ComponentClass, ComponentInstance } from './component'
+import { ComponentInstance } from './component'
 import { ComponentComputedOptions } from './componentOptions'
 
-export function resolveComputedOptions(
-  comp: ComponentClass
-): ComponentComputedOptions {
-  const computedOptions: ComponentComputedOptions = {}
-  const descriptors = Object.getOwnPropertyDescriptors(comp.prototype as any)
-  for (const key in descriptors) {
-    const d = descriptors[key]
-    if (d.get) {
-      computedOptions[key] = d.get
-      // there's no need to do anything for the setter
-      // as it's already defined on the prototype
-    }
-  }
-  return computedOptions
-}
-
 export function initializeComputed(
   instance: ComponentInstance,
   computedOptions: ComponentComputedOptions | undefined
index bd436fb96b6025b1f53a2623f2db0ec90989810b..bab8174599e467fffb3160d2a99548f02999cd61 100644 (file)
@@ -1,4 +1,4 @@
-import { ComponentInstance, Component } from './component'
+import { ComponentInstance } from './component'
 import { Slots } from './vdom'
 
 export type Data = Record<string, any>
@@ -10,8 +10,11 @@ export interface ComponentClassOptions<P = {}, This = ComponentInstance> {
   displayName?: string
 }
 
-export interface ComponentOptions<P = {}, D = {}, This = Component<P, D>>
-  extends ComponentClassOptions<P, This> {
+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
   // TODO other options
index 7a4e78976a4faf067a5529da81aff74f14a1b877..9dae489c2638138ac2edc9e180ad31ad923e61eb 100644 (file)
@@ -99,7 +99,7 @@ export function updateProps(instance: ComponentInstance, nextData: Data) {
   if (nextData != null) {
     const { props: nextProps, attrs: nextAttrs } = resolveProps(
       nextData,
-      instance.constructor.props
+      instance.$options.props
     )
     // unlock to temporarily allow mutatiing props
     unlock()
index 43bfd7251c380b6934604d712b1c82c8da22da48..33dc6ff5aff33c46c441565089893d7127ca498c 100644 (file)
@@ -25,8 +25,8 @@ const renderProxyHandlers = {
       // data
       return target.$data[key]
     } else if (
-      target.constructor.props != null &&
-      target.constructor.props.hasOwnProperty(key)
+      target.$options.props != null &&
+      target.$options.props.hasOwnProperty(key)
     ) {
       // props are only proxied if declared
       return target.$props[key]
@@ -61,8 +61,8 @@ const renderProxyHandlers = {
         return false
       }
       if (
-        target.constructor.props != null &&
-        target.constructor.props.hasOwnProperty(key)
+        target.$options.props != null &&
+        target.$options.props.hasOwnProperty(key)
       ) {
         // TODO warn props are immutable
         return false
index 8893a905b3bc0e64d9b956a85d6fead7dd8a21cb..b277c82280862ff0cd887e0f7568a5eb0b1d6926 100644 (file)
@@ -11,11 +11,7 @@ import {
 import { createTextVNode, cloneVNode } from './vdom'
 import { initializeState } from './componentState'
 import { initializeProps, resolveProps } from './componentProps'
-import {
-  initializeComputed,
-  resolveComputedOptions,
-  teardownComputed
-} from './componentComputed'
+import { initializeComputed, teardownComputed } from './componentComputed'
 import { initializeWatch, teardownWatch } from './componentWatch'
 import { ComponentOptions } from './componentOptions'
 import { createRenderProxy } from './componentProxy'
@@ -42,8 +38,8 @@ export function createComponentInstance(
   // then we finish the initialization by collecting properties set on the
   // instance
   initializeState(instance)
-  initializeComputed(instance, Component.computed)
-  initializeWatch(instance, Component.watch)
+  initializeComputed(instance, instance.$options.computed)
+  initializeWatch(instance, instance.$options.watch)
   instance.$slots = currentVNode.slots || EMPTY_OBJ
   if (instance.created) {
     instance.created.call(instance.$proxy)
@@ -93,7 +89,7 @@ export function initializeComponentInstance(instance: ComponentInstance) {
   }
   initializeProps(
     instance,
-    instance.constructor.props,
+    instance.$options.props,
     (currentVNode as VNode).data
   )
 }
@@ -212,8 +208,9 @@ export function createComponentClassFromOptions(
     const value = options[key]
     // name -> displayName
     if (key === 'name') {
-      AnonymousComponent.displayName = options.name
+      options.displayName = options.name
     } else if (typeof value === 'function') {
+      // lifecycle hook / data / render
       if (__COMPAT__) {
         if (key === 'render') {
           proto[key] = function() {
@@ -230,7 +227,6 @@ export function createComponentClassFromOptions(
         proto[key] = value
       }
     } else if (key === 'computed') {
-      AnonymousComponent.computed = value
       for (const computedKey in value) {
         const computed = value[computedKey]
         const isGet = typeof computed === 'function'
@@ -250,28 +246,41 @@ export function createComponentClassFromOptions(
         }
         proto[method] = value[method]
       }
-    } else {
-      ;(AnonymousComponent as any)[key] = value
     }
   }
   return AnonymousComponent as ComponentClass
 }
 
+// This is called in the base component constructor and the return value is
+// set on the instance as $options.
 export function resolveComponentOptions(
   Component: ComponentClass
 ): ComponentOptions {
   if (Component.options) {
     return Component.options
   }
-  const descriptors = Object.getOwnPropertyDescriptors(Component)
+  const staticDescriptors = Object.getOwnPropertyDescriptors(Component)
   const options = {} as any
-  for (const key in descriptors) {
-    const descriptor = descriptors[key]
-    if (descriptor.enumerable || descriptor.get) {
-      options[key] = descriptor.get ? descriptor.get() : descriptor.value
+  for (const key in staticDescriptors) {
+    const { enumerable, get, value } = staticDescriptors[key]
+    if (enumerable || get) {
+      options[key] = get ? get() : value
+    }
+  }
+  const instanceDescriptors = Object.getOwnPropertyDescriptors(
+    Component.prototype
+  )
+  for (const key in instanceDescriptors) {
+    const { get, value } = instanceDescriptors[key]
+    if (get) {
+      // computed properties
+      ;(options.computed || (options.computed = {}))[key] = get
+      // there's no need to do anything for the setter
+      // as it's already defined on the prototype
+    } else if (typeof value === 'function') {
+      ;(options.methods || (options.methods = {}))[key] = value
     }
   }
-  Component.computed = options.computed = resolveComputedOptions(Component)
   Component.options = options
   return options
 }