wip: render proxy
This commit is contained in:
parent
6ceb732114
commit
178c7c827e
@ -1,5 +1,5 @@
|
|||||||
import { VNode, normalizeVNode, VNodeChild } from './vnode'
|
import { VNode, normalizeVNode, VNodeChild } from './vnode'
|
||||||
import { ReactiveEffect } from '@vue/observer'
|
import { ReactiveEffect, observable } from '@vue/observer'
|
||||||
import { isFunction, EMPTY_OBJ } from '@vue/shared'
|
import { isFunction, EMPTY_OBJ } from '@vue/shared'
|
||||||
import { RenderProxyHandlers } from './componentProxy'
|
import { RenderProxyHandlers } from './componentProxy'
|
||||||
import { ComponentPropsOptions, PropValidator } from './componentProps'
|
import { ComponentPropsOptions, PropValidator } from './componentProps'
|
||||||
@ -30,6 +30,9 @@ export interface ComponentPublicProperties<P = Data, S = Data> {
|
|||||||
// TODO
|
// TODO
|
||||||
$refs: Data
|
$refs: Data
|
||||||
$slots: Data
|
$slots: Data
|
||||||
|
|
||||||
|
$root: ComponentInstance | null
|
||||||
|
$parent: ComponentInstance | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComponentOptions<
|
export interface ComponentOptions<
|
||||||
@ -147,7 +150,7 @@ export function setupStatefulComponent(instance: ComponentInstance) {
|
|||||||
if (Component.setup) {
|
if (Component.setup) {
|
||||||
currentInstance = instance
|
currentInstance = instance
|
||||||
// TODO should pass reactive props here
|
// TODO should pass reactive props here
|
||||||
instance.state = Component.setup.call(proxy, instance.props)
|
instance.state = observable(Component.setup.call(proxy, instance.props))
|
||||||
currentInstance = null
|
currentInstance = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1,55 @@
|
|||||||
export const RenderProxyHandlers = {}
|
import { ComponentInstance } from './component'
|
||||||
|
import { isObservable, unwrap } from '@vue/observer'
|
||||||
|
|
||||||
|
// TODO use proper implementation
|
||||||
|
function isValue(binding: any) {
|
||||||
|
return isObservable(binding) && unwrap(binding).hasOwnProperty('value')
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RenderProxyHandlers = {
|
||||||
|
get(target: ComponentInstance, key: string) {
|
||||||
|
const { state, props } = target
|
||||||
|
if (state.hasOwnProperty(key)) {
|
||||||
|
const value = state[key]
|
||||||
|
return isValue(value) ? value.value : value
|
||||||
|
} else if (props.hasOwnProperty(key)) {
|
||||||
|
return props[key]
|
||||||
|
} else {
|
||||||
|
switch (key) {
|
||||||
|
case '$state':
|
||||||
|
return target.state
|
||||||
|
case '$props':
|
||||||
|
return target.props
|
||||||
|
case '$attrs':
|
||||||
|
return target.attrs
|
||||||
|
case '$slots':
|
||||||
|
return target.slots
|
||||||
|
case '$refs':
|
||||||
|
return target.refs
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set(target: ComponentInstance, key: string, value: any): boolean {
|
||||||
|
const { state } = target
|
||||||
|
if (state.hasOwnProperty(key)) {
|
||||||
|
const binding = state[key]
|
||||||
|
if (isValue(binding)) {
|
||||||
|
binding.value = value
|
||||||
|
} else {
|
||||||
|
state[key] = value
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
if (__DEV__) {
|
||||||
|
if (key[0] === '$') {
|
||||||
|
// TODO warn attempt of mutating public property
|
||||||
|
} else if (target.props.hasOwnProperty(key)) {
|
||||||
|
// TODO warn attempt of mutating prop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -389,13 +389,16 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
queuePostFlushCb(instance.m)
|
queuePostFlushCb(instance.m)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// this is triggered by processComponent with `next` already set
|
// component update
|
||||||
|
// This is triggered by mutation of component's own state (next: null)
|
||||||
|
// OR parent calling processComponent (next: VNode)
|
||||||
const { next } = instance
|
const { next } = instance
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
next.component = instance
|
next.component = instance
|
||||||
instance.vnode = next
|
instance.vnode = next
|
||||||
instance.next = null
|
instance.next = null
|
||||||
resolveProps(instance, next.props, Component.props)
|
resolveProps(instance, next.props, Component.props)
|
||||||
|
// TODO slots
|
||||||
}
|
}
|
||||||
const prevTree = instance.subTree
|
const prevTree = instance.subTree
|
||||||
const nextTree = (instance.subTree = renderComponentRoot(instance))
|
const nextTree = (instance.subTree = renderComponentRoot(instance))
|
||||||
@ -738,8 +741,14 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
: getNextHostNode(vnode.component.subTree)
|
: getNextHostNode(vnode.component.subTree)
|
||||||
}
|
}
|
||||||
|
|
||||||
return function render(vnode: VNode, dom: HostNode): VNode {
|
return function render(vnode: VNode | null, dom: HostNode): VNode | null {
|
||||||
patch(dom._vnode, vnode, dom)
|
if (vnode == null) {
|
||||||
|
if (dom._vnode) {
|
||||||
|
unmount(dom._vnode, true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
patch(dom._vnode, vnode, dom)
|
||||||
|
}
|
||||||
flushPostFlushCbs()
|
flushPostFlushCbs()
|
||||||
return (dom._vnode = vnode)
|
return (dom._vnode = vnode)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user