refactor: reduce work in options -> class conversion
This commit is contained in:
parent
8e370efbaf
commit
8db26a504c
@ -5,7 +5,6 @@ import {
|
|||||||
APIMethods,
|
APIMethods,
|
||||||
LifecycleMethods
|
LifecycleMethods
|
||||||
} from './component'
|
} from './component'
|
||||||
import { Slots } from './vdom'
|
|
||||||
import { isArray, isObject, isFunction } from '@vue/shared'
|
import { isArray, isObject, isFunction } from '@vue/shared'
|
||||||
import { normalizePropsOptions } from './componentProps'
|
import { normalizePropsOptions } from './componentProps'
|
||||||
|
|
||||||
@ -22,9 +21,7 @@ export interface ComponentOptions<
|
|||||||
P = {},
|
P = {},
|
||||||
D = {},
|
D = {},
|
||||||
This = ComponentInstance<P, D>
|
This = ComponentInstance<P, D>
|
||||||
> extends ComponentClassOptions<P, This> {
|
> extends ComponentClassOptions<P, This>, APIMethods<P, D>, LifecycleMethods {
|
||||||
data?(): D
|
|
||||||
render?: (this: This, props: Readonly<Data>, slots: Slots, attrs: Data) => any
|
|
||||||
// TODO other options
|
// TODO other options
|
||||||
readonly [key: string]: any
|
readonly [key: string]: any
|
||||||
}
|
}
|
||||||
@ -164,6 +161,7 @@ export function mergeComponentOptions(to: any, from: any): ComponentOptions {
|
|||||||
if (isFunction(value) && isFunction(existing)) {
|
if (isFunction(value) && isFunction(existing)) {
|
||||||
if (key === 'data') {
|
if (key === 'data') {
|
||||||
// for data we need to merge the returned value
|
// for data we need to merge the returned value
|
||||||
|
// TODO: backwards compat requires recursive merge
|
||||||
res[key] = function() {
|
res[key] = function() {
|
||||||
return Object.assign(existing.call(this), value.call(this))
|
return Object.assign(existing.call(this), value.call(this))
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { VNodeFlags } from './flags'
|
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 { h } from './h'
|
||||||
import { VNode, MountedVNode, createFragment } from './vdom'
|
import { VNode, MountedVNode, createFragment } from './vdom'
|
||||||
import {
|
import {
|
||||||
@ -104,7 +104,7 @@ export function initializeComponentInstance(instance: ComponentInstance) {
|
|||||||
export function renderInstanceRoot(instance: ComponentInstance): VNode {
|
export function renderInstanceRoot(instance: ComponentInstance): VNode {
|
||||||
let vnode
|
let vnode
|
||||||
try {
|
try {
|
||||||
vnode = instance.render.call(
|
vnode = instance.$options.render.call(
|
||||||
instance.$proxy,
|
instance.$proxy,
|
||||||
instance.$props,
|
instance.$props,
|
||||||
instance.$slots,
|
instance.$slots,
|
||||||
@ -213,35 +213,26 @@ export function createComponentClassFromOptions(
|
|||||||
const proto = AnonymousComponent.prototype as any
|
const proto = AnonymousComponent.prototype as any
|
||||||
for (const key in options) {
|
for (const key in options) {
|
||||||
const value = options[key]
|
const value = options[key]
|
||||||
// name -> displayName
|
if (key === 'render') {
|
||||||
if (key === 'name') {
|
|
||||||
options.displayName = options.name
|
|
||||||
} else if (isFunction(value)) {
|
|
||||||
// lifecycle hook / data / render
|
|
||||||
if (__COMPAT__) {
|
if (__COMPAT__) {
|
||||||
if (key === 'render') {
|
options.render = function() {
|
||||||
proto[key] = function() {
|
return value.call(this, h)
|
||||||
return value.call(this, h)
|
|
||||||
}
|
|
||||||
} else if (key === 'beforeDestroy') {
|
|
||||||
proto.beforeUnmount = value
|
|
||||||
} else if (key === 'destroyed') {
|
|
||||||
proto.unmounted = value
|
|
||||||
} else {
|
|
||||||
proto[key] = value
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
proto[key] = value
|
|
||||||
}
|
}
|
||||||
|
// so that we can call instance.render directly
|
||||||
|
proto.render = options.render
|
||||||
} else if (key === 'computed') {
|
} else if (key === 'computed') {
|
||||||
|
// create computed setters on prototype
|
||||||
|
// (getters are handled by the render proxy)
|
||||||
for (const computedKey in value) {
|
for (const computedKey in value) {
|
||||||
const computed = value[computedKey]
|
const computed = value[computedKey]
|
||||||
const isGet = isFunction(computed)
|
const set = isObject(computed) && computed.set
|
||||||
Object.defineProperty(proto, computedKey, {
|
if (set) {
|
||||||
configurable: true,
|
Object.defineProperty(proto, computedKey, {
|
||||||
get: isGet ? computed : computed.get,
|
configurable: true,
|
||||||
set: isGet ? undefined : computed.set
|
set
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (key === 'methods') {
|
} else if (key === 'methods') {
|
||||||
for (const method in value) {
|
for (const method in value) {
|
||||||
@ -253,6 +244,18 @@ export function createComponentClassFromOptions(
|
|||||||
}
|
}
|
||||||
proto[method] = value[method]
|
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
|
return AnonymousComponent as ComponentClass
|
||||||
|
Loading…
Reference in New Issue
Block a user