refactor: improve functional patch
This commit is contained in:
parent
fc5aa6d0be
commit
f5700245b0
@ -76,10 +76,9 @@ export interface RendererOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FunctionalHandle {
|
export interface FunctionalHandle {
|
||||||
current: VNode
|
prev: VNode
|
||||||
prevTree: VNode
|
next: VNode
|
||||||
runner: Autorun
|
update: Autorun
|
||||||
forceUpdate: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSchedulerError(err => handleError(err, null, ErrorTypes.SCHEDULER))
|
handleSchedulerError(err => handleError(err, null, ErrorTypes.SCHEDULER))
|
||||||
@ -265,27 +264,20 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handle: FunctionalHandle = (vnode.handle = {
|
const handle: FunctionalHandle = (vnode.handle = {
|
||||||
current: vnode,
|
prev: vnode,
|
||||||
prevTree: null as any,
|
next: null as any,
|
||||||
runner: null as any,
|
update: null as any
|
||||||
forceUpdate: null as any
|
|
||||||
})
|
|
||||||
|
|
||||||
const queueUpdate = (handle.forceUpdate = () => {
|
|
||||||
queueJob(handle.runner)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const doMount = () => {
|
const doMount = () => {
|
||||||
handle.runner = autorun(
|
handle.update = autorun(
|
||||||
() => {
|
() => {
|
||||||
if (!handle.prevTree) {
|
if (!handle.next) {
|
||||||
// initial mount
|
// initial mount
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
pushWarningContext(vnode)
|
pushWarningContext(vnode)
|
||||||
}
|
}
|
||||||
const subTree = (handle.prevTree = vnode.children = renderFunctionalRoot(
|
const subTree = (vnode.children = renderFunctionalRoot(vnode))
|
||||||
vnode
|
|
||||||
))
|
|
||||||
queueEffect(() => {
|
queueEffect(() => {
|
||||||
vnode.el = subTree.el as RenderNode
|
vnode.el = subTree.el as RenderNode
|
||||||
})
|
})
|
||||||
@ -298,7 +290,7 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scheduler: queueUpdate
|
scheduler: queueJob
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -311,7 +303,7 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
doMount()
|
doMount()
|
||||||
// cleanup if mount is invalidated before committed
|
// cleanup if mount is invalidated before committed
|
||||||
return () => {
|
return () => {
|
||||||
stop(handle.runner)
|
stop(handle.update)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -319,21 +311,19 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
|
|
||||||
function updateFunctionalComponent(handle: FunctionalHandle, isSVG: boolean) {
|
function updateFunctionalComponent(handle: FunctionalHandle, isSVG: boolean) {
|
||||||
// mounted
|
// mounted
|
||||||
const { prevTree, current } = handle
|
const { prev, next } = handle
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
pushWarningContext(current)
|
pushWarningContext(next)
|
||||||
}
|
}
|
||||||
const nextTree = (handle.prevTree = current.children = renderFunctionalRoot(
|
const nextTree = (next.children = renderFunctionalRoot(next))
|
||||||
current
|
|
||||||
))
|
|
||||||
queueEffect(() => {
|
queueEffect(() => {
|
||||||
current.el = nextTree.el
|
next.el = nextTree.el
|
||||||
})
|
})
|
||||||
patch(
|
patch(
|
||||||
prevTree as MountedVNode,
|
prev.children as MountedVNode,
|
||||||
nextTree,
|
nextTree,
|
||||||
platformParentNode(current.el),
|
platformParentNode(prev.el),
|
||||||
current as MountedVNode,
|
next as MountedVNode,
|
||||||
isSVG
|
isSVG
|
||||||
)
|
)
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
@ -618,10 +608,11 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
function patchFunctionalComponent(prevVNode: MountedVNode, nextVNode: VNode) {
|
function patchFunctionalComponent(prevVNode: MountedVNode, nextVNode: VNode) {
|
||||||
const prevTree = prevVNode.children as VNode
|
const prevTree = prevVNode.children as VNode
|
||||||
const handle = (nextVNode.handle = prevVNode.handle as FunctionalHandle)
|
const handle = (nextVNode.handle = prevVNode.handle as FunctionalHandle)
|
||||||
handle.current = nextVNode
|
handle.prev = prevVNode
|
||||||
|
handle.next = nextVNode
|
||||||
|
|
||||||
if (shouldUpdateComponent(prevVNode, nextVNode)) {
|
if (shouldUpdateComponent(prevVNode, nextVNode)) {
|
||||||
handle.forceUpdate()
|
queueJob(handle.update)
|
||||||
} else if (prevTree.flags & VNodeFlags.COMPONENT) {
|
} else if (prevTree.flags & VNodeFlags.COMPONENT) {
|
||||||
// functional component returned another component
|
// functional component returned another component
|
||||||
prevTree.contextVNode = nextVNode
|
prevTree.contextVNode = nextVNode
|
||||||
@ -1182,7 +1173,7 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// functional
|
// functional
|
||||||
stop((handle as FunctionalHandle).runner)
|
stop((handle as FunctionalHandle).update)
|
||||||
unmount(children as MountedVNode)
|
unmount(children as MountedVNode)
|
||||||
}
|
}
|
||||||
} else if (flags & VNodeFlags.PORTAL) {
|
} else if (flags & VNodeFlags.PORTAL) {
|
||||||
@ -1293,12 +1284,12 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
$options: { beforeMount, renderTracked, renderTriggered }
|
$options: { beforeMount, renderTracked, renderTriggered }
|
||||||
} = instance
|
} = instance
|
||||||
|
|
||||||
const queueUpdate = (instance.$forceUpdate = () => {
|
instance.$forceUpdate = () => {
|
||||||
queueJob(instance._updateHandle)
|
queueJob(instance._updateHandle)
|
||||||
})
|
}
|
||||||
|
|
||||||
const autorunOptions: AutorunOptions = {
|
const autorunOptions: AutorunOptions = {
|
||||||
scheduler: queueUpdate
|
scheduler: queueJob
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
|
Loading…
Reference in New Issue
Block a user