fix(keep-alive): should update re-activated component with latest props

This commit is contained in:
Evan You 2020-03-24 10:28:00 -04:00
parent bfae9b2e55
commit 123738727a
3 changed files with 55 additions and 12 deletions

View File

@ -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`)
})
}) })
}) })

View File

@ -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!)

View File

@ -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(