wip: render proxy
This commit is contained in:
parent
6ceb732114
commit
178c7c827e
@ -1,5 +1,5 @@
|
||||
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 { RenderProxyHandlers } from './componentProxy'
|
||||
import { ComponentPropsOptions, PropValidator } from './componentProps'
|
||||
@ -30,6 +30,9 @@ export interface ComponentPublicProperties<P = Data, S = Data> {
|
||||
// TODO
|
||||
$refs: Data
|
||||
$slots: Data
|
||||
|
||||
$root: ComponentInstance | null
|
||||
$parent: ComponentInstance | null
|
||||
}
|
||||
|
||||
export interface ComponentOptions<
|
||||
@ -147,7 +150,7 @@ export function setupStatefulComponent(instance: ComponentInstance) {
|
||||
if (Component.setup) {
|
||||
currentInstance = instance
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
} 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
|
||||
if (next != null) {
|
||||
next.component = instance
|
||||
instance.vnode = next
|
||||
instance.next = null
|
||||
resolveProps(instance, next.props, Component.props)
|
||||
// TODO slots
|
||||
}
|
||||
const prevTree = instance.subTree
|
||||
const nextTree = (instance.subTree = renderComponentRoot(instance))
|
||||
@ -738,8 +741,14 @@ export function createRenderer(options: RendererOptions) {
|
||||
: getNextHostNode(vnode.component.subTree)
|
||||
}
|
||||
|
||||
return function render(vnode: VNode, dom: HostNode): VNode {
|
||||
return function render(vnode: VNode | null, dom: HostNode): VNode | null {
|
||||
if (vnode == null) {
|
||||
if (dom._vnode) {
|
||||
unmount(dom._vnode, true)
|
||||
}
|
||||
} else {
|
||||
patch(dom._vnode, vnode, dom)
|
||||
}
|
||||
flushPostFlushCbs()
|
||||
return (dom._vnode = vnode)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user