refactor: access all options from instance.$options
This commit is contained in:
parent
62214fa42e
commit
7bc28a6e61
@ -99,6 +99,7 @@ export interface ComponentInstance<P = {}, D = {}>
|
|||||||
$slots: Slots
|
$slots: Slots
|
||||||
$root: ComponentInstance
|
$root: ComponentInstance
|
||||||
$children: ComponentInstance[]
|
$children: ComponentInstance[]
|
||||||
|
$options: ComponentOptions<P, D>
|
||||||
|
|
||||||
_updateHandle: Autorun
|
_updateHandle: Autorun
|
||||||
_queueJob: ((fn: () => void) => void)
|
_queueJob: ((fn: () => void) => void)
|
||||||
@ -120,7 +121,7 @@ class InternalComponent implements PublicInstanceMethods {
|
|||||||
$root: ComponentInstance | null = null
|
$root: ComponentInstance | null = null
|
||||||
$parent: ComponentInstance | null = null
|
$parent: ComponentInstance | null = null
|
||||||
$children: ComponentInstance[] = []
|
$children: ComponentInstance[] = []
|
||||||
$options: ComponentOptions
|
$options: ComponentOptions | null = null
|
||||||
$refs: Record<string, ComponentInstance | RenderNode> = {}
|
$refs: Record<string, ComponentInstance | RenderNode> = {}
|
||||||
$proxy: any = null
|
$proxy: any = null
|
||||||
|
|
||||||
|
@ -1,24 +1,8 @@
|
|||||||
import { NOOP } from './utils'
|
import { NOOP } from './utils'
|
||||||
import { computed, stop, ComputedGetter } from '@vue/observer'
|
import { computed, stop, ComputedGetter } from '@vue/observer'
|
||||||
import { ComponentClass, ComponentInstance } from './component'
|
import { ComponentInstance } from './component'
|
||||||
import { ComponentComputedOptions } from './componentOptions'
|
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(
|
export function initializeComputed(
|
||||||
instance: ComponentInstance,
|
instance: ComponentInstance,
|
||||||
computedOptions: ComponentComputedOptions | undefined
|
computedOptions: ComponentComputedOptions | undefined
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ComponentInstance, Component } from './component'
|
import { ComponentInstance } from './component'
|
||||||
import { Slots } from './vdom'
|
import { Slots } from './vdom'
|
||||||
|
|
||||||
export type Data = Record<string, any>
|
export type Data = Record<string, any>
|
||||||
@ -10,8 +10,11 @@ export interface ComponentClassOptions<P = {}, This = ComponentInstance> {
|
|||||||
displayName?: string
|
displayName?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComponentOptions<P = {}, D = {}, This = Component<P, D>>
|
export interface ComponentOptions<
|
||||||
extends ComponentClassOptions<P, This> {
|
P = {},
|
||||||
|
D = {},
|
||||||
|
This = ComponentInstance<P, D>
|
||||||
|
> extends ComponentClassOptions<P, This> {
|
||||||
data?(): D
|
data?(): D
|
||||||
render?: (this: This, props: Readonly<Data>, slots: Slots, attrs: Data) => any
|
render?: (this: This, props: Readonly<Data>, slots: Slots, attrs: Data) => any
|
||||||
// TODO other options
|
// TODO other options
|
||||||
|
@ -99,7 +99,7 @@ export function updateProps(instance: ComponentInstance, nextData: Data) {
|
|||||||
if (nextData != null) {
|
if (nextData != null) {
|
||||||
const { props: nextProps, attrs: nextAttrs } = resolveProps(
|
const { props: nextProps, attrs: nextAttrs } = resolveProps(
|
||||||
nextData,
|
nextData,
|
||||||
instance.constructor.props
|
instance.$options.props
|
||||||
)
|
)
|
||||||
// unlock to temporarily allow mutatiing props
|
// unlock to temporarily allow mutatiing props
|
||||||
unlock()
|
unlock()
|
||||||
|
@ -25,8 +25,8 @@ const renderProxyHandlers = {
|
|||||||
// data
|
// data
|
||||||
return target.$data[key]
|
return target.$data[key]
|
||||||
} else if (
|
} else if (
|
||||||
target.constructor.props != null &&
|
target.$options.props != null &&
|
||||||
target.constructor.props.hasOwnProperty(key)
|
target.$options.props.hasOwnProperty(key)
|
||||||
) {
|
) {
|
||||||
// props are only proxied if declared
|
// props are only proxied if declared
|
||||||
return target.$props[key]
|
return target.$props[key]
|
||||||
@ -61,8 +61,8 @@ const renderProxyHandlers = {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
target.constructor.props != null &&
|
target.$options.props != null &&
|
||||||
target.constructor.props.hasOwnProperty(key)
|
target.$options.props.hasOwnProperty(key)
|
||||||
) {
|
) {
|
||||||
// TODO warn props are immutable
|
// TODO warn props are immutable
|
||||||
return false
|
return false
|
||||||
|
@ -11,11 +11,7 @@ import {
|
|||||||
import { createTextVNode, cloneVNode } from './vdom'
|
import { createTextVNode, cloneVNode } from './vdom'
|
||||||
import { initializeState } from './componentState'
|
import { initializeState } from './componentState'
|
||||||
import { initializeProps, resolveProps } from './componentProps'
|
import { initializeProps, resolveProps } from './componentProps'
|
||||||
import {
|
import { initializeComputed, teardownComputed } from './componentComputed'
|
||||||
initializeComputed,
|
|
||||||
resolveComputedOptions,
|
|
||||||
teardownComputed
|
|
||||||
} from './componentComputed'
|
|
||||||
import { initializeWatch, teardownWatch } from './componentWatch'
|
import { initializeWatch, teardownWatch } from './componentWatch'
|
||||||
import { ComponentOptions } from './componentOptions'
|
import { ComponentOptions } from './componentOptions'
|
||||||
import { createRenderProxy } from './componentProxy'
|
import { createRenderProxy } from './componentProxy'
|
||||||
@ -42,8 +38,8 @@ export function createComponentInstance(
|
|||||||
// then we finish the initialization by collecting properties set on the
|
// then we finish the initialization by collecting properties set on the
|
||||||
// instance
|
// instance
|
||||||
initializeState(instance)
|
initializeState(instance)
|
||||||
initializeComputed(instance, Component.computed)
|
initializeComputed(instance, instance.$options.computed)
|
||||||
initializeWatch(instance, Component.watch)
|
initializeWatch(instance, instance.$options.watch)
|
||||||
instance.$slots = currentVNode.slots || EMPTY_OBJ
|
instance.$slots = currentVNode.slots || EMPTY_OBJ
|
||||||
if (instance.created) {
|
if (instance.created) {
|
||||||
instance.created.call(instance.$proxy)
|
instance.created.call(instance.$proxy)
|
||||||
@ -93,7 +89,7 @@ export function initializeComponentInstance(instance: ComponentInstance) {
|
|||||||
}
|
}
|
||||||
initializeProps(
|
initializeProps(
|
||||||
instance,
|
instance,
|
||||||
instance.constructor.props,
|
instance.$options.props,
|
||||||
(currentVNode as VNode).data
|
(currentVNode as VNode).data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -212,8 +208,9 @@ export function createComponentClassFromOptions(
|
|||||||
const value = options[key]
|
const value = options[key]
|
||||||
// name -> displayName
|
// name -> displayName
|
||||||
if (key === 'name') {
|
if (key === 'name') {
|
||||||
AnonymousComponent.displayName = options.name
|
options.displayName = options.name
|
||||||
} else if (typeof value === 'function') {
|
} else if (typeof value === 'function') {
|
||||||
|
// lifecycle hook / data / render
|
||||||
if (__COMPAT__) {
|
if (__COMPAT__) {
|
||||||
if (key === 'render') {
|
if (key === 'render') {
|
||||||
proto[key] = function() {
|
proto[key] = function() {
|
||||||
@ -230,7 +227,6 @@ export function createComponentClassFromOptions(
|
|||||||
proto[key] = value
|
proto[key] = value
|
||||||
}
|
}
|
||||||
} else if (key === 'computed') {
|
} else if (key === 'computed') {
|
||||||
AnonymousComponent.computed = value
|
|
||||||
for (const computedKey in value) {
|
for (const computedKey in value) {
|
||||||
const computed = value[computedKey]
|
const computed = value[computedKey]
|
||||||
const isGet = typeof computed === 'function'
|
const isGet = typeof computed === 'function'
|
||||||
@ -250,28 +246,41 @@ export function createComponentClassFromOptions(
|
|||||||
}
|
}
|
||||||
proto[method] = value[method]
|
proto[method] = value[method]
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
;(AnonymousComponent as any)[key] = value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AnonymousComponent as ComponentClass
|
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(
|
export function resolveComponentOptions(
|
||||||
Component: ComponentClass
|
Component: ComponentClass
|
||||||
): ComponentOptions {
|
): ComponentOptions {
|
||||||
if (Component.options) {
|
if (Component.options) {
|
||||||
return Component.options
|
return Component.options
|
||||||
}
|
}
|
||||||
const descriptors = Object.getOwnPropertyDescriptors(Component)
|
const staticDescriptors = Object.getOwnPropertyDescriptors(Component)
|
||||||
const options = {} as any
|
const options = {} as any
|
||||||
for (const key in descriptors) {
|
for (const key in staticDescriptors) {
|
||||||
const descriptor = descriptors[key]
|
const { enumerable, get, value } = staticDescriptors[key]
|
||||||
if (descriptor.enumerable || descriptor.get) {
|
if (enumerable || get) {
|
||||||
options[key] = descriptor.get ? descriptor.get() : descriptor.value
|
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
|
Component.options = options
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user