wip: $state -> $data

This commit is contained in:
Evan You 2019-06-19 17:08:42 +08:00
parent 5228f0343b
commit 976844790e
2 changed files with 34 additions and 28 deletions

View File

@ -17,7 +17,7 @@ export type Data = { [key: string]: any }
// public properties exposed on the proxy, which is used as the render context // public properties exposed on the proxy, which is used as the render context
// in templates (as `this` in the render option) // in templates (as `this` in the render option)
export type ComponentRenderProxy<P = {}, S = {}, PublicProps = P> = { export type ComponentRenderProxy<P = {}, S = {}, PublicProps = P> = {
$state: S $data: S
$props: PublicProps $props: PublicProps
$attrs: Data $attrs: Data
$refs: Data $refs: Data
@ -97,6 +97,8 @@ interface SetupContext {
attrs: Data attrs: Data
slots: Slots slots: Slots
refs: Data refs: Data
parent: ComponentInstance | null
root: ComponentInstance
emit: ((event: string, ...args: any[]) => void) emit: ((event: string, ...args: any[]) => void)
} }
@ -112,7 +114,7 @@ export type ComponentInstance<P = Data, S = Data> = {
render: RenderFunction<P, S> | null render: RenderFunction<P, S> | null
// the rest are only for stateful components // the rest are only for stateful components
state: S data: S
props: P props: P
renderProxy: ComponentRenderProxy | null renderProxy: ComponentRenderProxy | null
propsProxy: P | null propsProxy: P | null
@ -193,7 +195,7 @@ export function createComponentInstance(
effects: null, effects: null,
// public properties // public properties
state: EMPTY_OBJ, data: EMPTY_OBJ,
props: EMPTY_OBJ, props: EMPTY_OBJ,
attrs: EMPTY_OBJ, attrs: EMPTY_OBJ,
slots: EMPTY_OBJ, slots: EMPTY_OBJ,
@ -217,10 +219,7 @@ export let currentInstance: ComponentInstance | null = null
export function setupStatefulComponent(instance: ComponentInstance) { export function setupStatefulComponent(instance: ComponentInstance) {
const Component = instance.type as ComponentOptions const Component = instance.type as ComponentOptions
// 1. create render proxy // 1. create render proxy
const proxy = (instance.renderProxy = new Proxy( instance.renderProxy = new Proxy(instance, RenderProxyHandlers) as any
instance,
RenderProxyHandlers
) as any)
// 2. call setup() // 2. call setup()
const { setup } = Component const { setup } = Component
if (setup) { if (setup) {
@ -233,14 +232,14 @@ export function setupStatefulComponent(instance: ComponentInstance) {
: null) : null)
const setupContext = (instance.setupContext = const setupContext = (instance.setupContext =
setup.length > 1 ? createSetupContext(instance) : null) setup.length > 1 ? createSetupContext(instance) : null)
const setupResult = setup.call(proxy, propsProxy, setupContext) const setupResult = setup.call(null, propsProxy, setupContext)
if (isFunction(setupResult)) { if (isFunction(setupResult)) {
// setup returned an inline render function // setup returned an inline render function
instance.render = setupResult instance.render = setupResult
} else { } else {
// setup returned bindings. // setup returned bindings.
// assuming a render function compiled from template is present. // assuming a render function compiled from template is present.
instance.state = state(setupResult) instance.data = state(setupResult)
if (__DEV__ && !Component.render) { if (__DEV__ && !Component.render) {
// TODO warn missing render fn // TODO warn missing render fn
} }
@ -269,7 +268,9 @@ function createSetupContext(instance: ComponentInstance): SetupContext {
attrs: new Proxy(instance, SetupProxyHandlers.attrs), attrs: new Proxy(instance, SetupProxyHandlers.attrs),
slots: new Proxy(instance, SetupProxyHandlers.slots), slots: new Proxy(instance, SetupProxyHandlers.slots),
refs: new Proxy(instance, SetupProxyHandlers.refs), refs: new Proxy(instance, SetupProxyHandlers.refs),
emit: instance.emit emit: instance.emit,
parent: instance.parent,
root: instance.root
} as any } as any
return __DEV__ ? Object.freeze(context) : context return __DEV__ ? Object.freeze(context) : context
} }
@ -284,7 +285,9 @@ export function renderComponentRoot(instance: ComponentInstance): VNode {
slots, slots,
attrs, attrs,
refs, refs,
emit emit,
parent,
root
} = instance } = instance
if (vnode.shapeFlag & STATEFUL_COMPONENT) { if (vnode.shapeFlag & STATEFUL_COMPONENT) {
return normalizeVNode( return normalizeVNode(
@ -292,13 +295,18 @@ export function renderComponentRoot(instance: ComponentInstance): VNode {
) )
} else { } else {
// functional // functional
const render = Component as FunctionalComponent
return normalizeVNode( return normalizeVNode(
(Component as FunctionalComponent)(props, { render.length > 1
attrs, ? render(props, {
slots, attrs,
refs, slots,
emit refs,
}) emit,
parent,
root
})
: render(props, null as any)
) )
} }
} }

View File

@ -2,17 +2,17 @@ import { ComponentInstance } from './component'
export const RenderProxyHandlers = { export const RenderProxyHandlers = {
get(target: ComponentInstance, key: string) { get(target: ComponentInstance, key: string) {
const { state, props } = target const { data, props } = target
if (state.hasOwnProperty(key)) { if (data.hasOwnProperty(key)) {
return state[key] return data[key]
} else if (props.hasOwnProperty(key)) { } else if (props.hasOwnProperty(key)) {
return props[key] return props[key]
} else { } else {
switch (key) { switch (key) {
case '$state': case '$data':
return target.state return data
case '$props': case '$props':
return target.props return props
case '$attrs': case '$attrs':
return target.attrs return target.attrs
case '$slots': case '$slots':
@ -23,8 +23,6 @@ export const RenderProxyHandlers = {
return target.parent return target.parent
case '$root': case '$root':
return target.root return target.root
case '$el':
return target.vnode && target.vnode.el
case '$emit': case '$emit':
return target.emit return target.emit
default: default:
@ -33,9 +31,9 @@ export const RenderProxyHandlers = {
} }
}, },
set(target: ComponentInstance, key: string, value: any): boolean { set(target: ComponentInstance, key: string, value: any): boolean {
const { state } = target const { data } = target
if (state.hasOwnProperty(key)) { if (data.hasOwnProperty(key)) {
state[key] = value data[key] = value
return true return true
} else { } else {
if (__DEV__) { if (__DEV__) {