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
-import { ComponentInstance, Component } from './component'
+import { ComponentInstance } from './component'
import { Slots } from './vdom'
export type Data = Record<string, any>
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
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'
// 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)
}
initializeProps(
instance,
- instance.constructor.props,
+ instance.$options.props,
(currentVNode as VNode).data
)
}
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() {
proto[key] = value
}
} else if (key === 'computed') {
- AnonymousComponent.computed = value
for (const computedKey in value) {
const computed = value[computedKey]
const isGet = typeof computed === 'function'
}
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
}