fix(keep-alive): should update re-activated component with latest props
This commit is contained in:
parent
bfae9b2e55
commit
123738727a
@ -531,5 +531,32 @@ describe('KeepAlive', () => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
expect(Foo.unmounted).not.toHaveBeenCalled()
|
expect(Foo.unmounted).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should update re-activated component if props have changed', async () => {
|
||||||
|
const Foo = (props: { n: number }) => props.n
|
||||||
|
|
||||||
|
const toggle = ref(true)
|
||||||
|
const n = ref(0)
|
||||||
|
|
||||||
|
const App = {
|
||||||
|
setup() {
|
||||||
|
return () =>
|
||||||
|
h(KeepAlive, () => (toggle.value ? h(Foo, { n: n.value }) : null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render(h(App), root)
|
||||||
|
expect(serializeInner(root)).toBe(`0`)
|
||||||
|
|
||||||
|
toggle.value = false
|
||||||
|
await nextTick()
|
||||||
|
expect(serializeInner(root)).toBe(`<!---->`)
|
||||||
|
|
||||||
|
n.value++
|
||||||
|
await nextTick()
|
||||||
|
toggle.value = true
|
||||||
|
await nextTick()
|
||||||
|
expect(serializeInner(root)).toBe(`1`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -41,7 +41,9 @@ export interface KeepAliveSink {
|
|||||||
activate: (
|
activate: (
|
||||||
vnode: VNode,
|
vnode: VNode,
|
||||||
container: RendererElement,
|
container: RendererElement,
|
||||||
anchor: RendererNode | null
|
anchor: RendererNode | null,
|
||||||
|
isSVG: boolean,
|
||||||
|
optimized: boolean
|
||||||
) => void
|
) => void
|
||||||
deactivate: (vnode: VNode) => void
|
deactivate: (vnode: VNode) => void
|
||||||
}
|
}
|
||||||
@ -78,6 +80,7 @@ const KeepAliveImpl = {
|
|||||||
const sink = instance.sink as KeepAliveSink
|
const sink = instance.sink as KeepAliveSink
|
||||||
const {
|
const {
|
||||||
renderer: {
|
renderer: {
|
||||||
|
p: patch,
|
||||||
m: move,
|
m: move,
|
||||||
um: _unmount,
|
um: _unmount,
|
||||||
o: { createElement }
|
o: { createElement }
|
||||||
@ -86,13 +89,24 @@ const KeepAliveImpl = {
|
|||||||
} = sink
|
} = sink
|
||||||
const storageContainer = createElement('div')
|
const storageContainer = createElement('div')
|
||||||
|
|
||||||
sink.activate = (vnode, container, anchor) => {
|
sink.activate = (vnode, container, anchor, isSVG, optimized) => {
|
||||||
|
const child = vnode.component!
|
||||||
move(vnode, container, anchor, MoveType.ENTER, parentSuspense)
|
move(vnode, container, anchor, MoveType.ENTER, parentSuspense)
|
||||||
|
// in case props have changed
|
||||||
|
patch(
|
||||||
|
child.vnode,
|
||||||
|
vnode,
|
||||||
|
container,
|
||||||
|
anchor,
|
||||||
|
instance,
|
||||||
|
parentSuspense,
|
||||||
|
isSVG,
|
||||||
|
optimized
|
||||||
|
)
|
||||||
queuePostRenderEffect(() => {
|
queuePostRenderEffect(() => {
|
||||||
const component = vnode.component!
|
child.isDeactivated = false
|
||||||
component.isDeactivated = false
|
if (child.a) {
|
||||||
if (component.a) {
|
invokeHooks(child.a)
|
||||||
invokeHooks(component.a)
|
|
||||||
}
|
}
|
||||||
}, parentSuspense)
|
}, parentSuspense)
|
||||||
}
|
}
|
||||||
@ -181,7 +195,7 @@ const KeepAliveImpl = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const key = vnode.key == null ? comp : vnode.key
|
const key = vnode.key == null ? comp : vnode.key
|
||||||
const cached = cache.get(key)
|
const cachedVNode = cache.get(key)
|
||||||
|
|
||||||
// clone vnode if it's reused because we are going to mutate it
|
// clone vnode if it's reused because we are going to mutate it
|
||||||
if (vnode.el) {
|
if (vnode.el) {
|
||||||
@ -189,11 +203,11 @@ const KeepAliveImpl = {
|
|||||||
}
|
}
|
||||||
cache.set(key, vnode)
|
cache.set(key, vnode)
|
||||||
|
|
||||||
if (cached) {
|
if (cachedVNode) {
|
||||||
// copy over mounted state
|
// copy over mounted state
|
||||||
vnode.el = cached.el
|
vnode.el = cachedVNode.el
|
||||||
vnode.anchor = cached.anchor
|
vnode.anchor = cachedVNode.anchor
|
||||||
vnode.component = cached.component
|
vnode.component = cachedVNode.component
|
||||||
if (vnode.transition) {
|
if (vnode.transition) {
|
||||||
// recursively update transition hooks on subTree
|
// recursively update transition hooks on subTree
|
||||||
setTransitionHooks(vnode, vnode.transition!)
|
setTransitionHooks(vnode, vnode.transition!)
|
||||||
|
@ -946,7 +946,9 @@ function baseCreateRenderer(
|
|||||||
;(parentComponent!.sink as KeepAliveSink).activate(
|
;(parentComponent!.sink as KeepAliveSink).activate(
|
||||||
n2,
|
n2,
|
||||||
container,
|
container,
|
||||||
anchor
|
anchor,
|
||||||
|
isSVG,
|
||||||
|
optimized
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
mountComponent(
|
mountComponent(
|
||||||
|
Loading…
Reference in New Issue
Block a user