|
|
@@ -286,6 +286,101 @@ describe('hot module replacement', () => {
|
|
|
expect(deactivatedSpy).toHaveBeenCalledTimes(1)
|
|
|
})
|
|
|
|
|
|
+ test('reload deactivated KeepAlive child', async () => {
|
|
|
+ const root = document.createElement('div')
|
|
|
+ document.body.appendChild(root)
|
|
|
+ const childId = 'test-child-keep-alive-deactivated'
|
|
|
+ const oldUnmountSpy = vi.fn()
|
|
|
+ const oldActiveSpy = vi.fn()
|
|
|
+ const oldDeactivatedSpy = vi.fn()
|
|
|
+ const newUnmountSpy = vi.fn()
|
|
|
+ const newMountSpy = vi.fn()
|
|
|
+ const newActiveSpy = vi.fn()
|
|
|
+ const newDeactivatedSpy = vi.fn()
|
|
|
+
|
|
|
+ const Child = defineVaporComponent({
|
|
|
+ __hmrId: childId,
|
|
|
+ setup() {
|
|
|
+ onUnmounted(oldUnmountSpy)
|
|
|
+ onActivated(oldActiveSpy)
|
|
|
+ onDeactivated(oldDeactivatedSpy)
|
|
|
+ const count = ref(0)
|
|
|
+ return { count }
|
|
|
+ },
|
|
|
+ render: compileToFunction(`<div>{{ count }}</div>`),
|
|
|
+ })
|
|
|
+ createRecord(childId, Child as any)
|
|
|
+
|
|
|
+ const Parent = defineVaporComponent({
|
|
|
+ __hmrId: 'parentId-keep-alive-deactivated',
|
|
|
+ components: { Child },
|
|
|
+ setup() {
|
|
|
+ const toggle = ref(true)
|
|
|
+ return { toggle }
|
|
|
+ },
|
|
|
+ render: compileToFunction(
|
|
|
+ `<button @click="toggle = !toggle" />
|
|
|
+ <KeepAlive><Child v-if="toggle" /></KeepAlive>`,
|
|
|
+ ),
|
|
|
+ })
|
|
|
+
|
|
|
+ define(Parent).create().mount(root)
|
|
|
+ expect(root.innerHTML).toBe(`<button></button><div>0</div><!--if-->`)
|
|
|
+ expect(oldActiveSpy).toHaveBeenCalledTimes(1)
|
|
|
+ expect(oldDeactivatedSpy).toHaveBeenCalledTimes(0)
|
|
|
+ expect(oldUnmountSpy).toHaveBeenCalledTimes(0)
|
|
|
+
|
|
|
+ // deactivate and move child into KeepAlive cache
|
|
|
+ triggerEvent('click', root.children[0] as Element)
|
|
|
+ await nextTick()
|
|
|
+ expect(root.innerHTML).toBe(`<button></button><!--if-->`)
|
|
|
+ expect(oldDeactivatedSpy).toHaveBeenCalledTimes(1)
|
|
|
+ expect(oldUnmountSpy).toHaveBeenCalledTimes(0)
|
|
|
+
|
|
|
+ // reload while child is cached but inactive
|
|
|
+ reload(childId, {
|
|
|
+ __hmrId: childId,
|
|
|
+ __vapor: true,
|
|
|
+ setup() {
|
|
|
+ onMounted(newMountSpy)
|
|
|
+ onUnmounted(newUnmountSpy)
|
|
|
+ onActivated(newActiveSpy)
|
|
|
+ onDeactivated(newDeactivatedSpy)
|
|
|
+ const count = ref(1)
|
|
|
+ return { count }
|
|
|
+ },
|
|
|
+ render: compileToFunction(`<div>{{ count }}</div>`),
|
|
|
+ })
|
|
|
+ await nextTick()
|
|
|
+ expect(root.innerHTML).toBe(`<button></button><!--if-->`)
|
|
|
+ // old cached instance should be unmounted during KeepAlive HMR rerender
|
|
|
+ expect(oldUnmountSpy).toHaveBeenCalledTimes(1)
|
|
|
+
|
|
|
+ // re-activate should render the new component instance
|
|
|
+ triggerEvent('click', root.children[0] as Element)
|
|
|
+ await nextTick()
|
|
|
+ expect(root.innerHTML).toBe(`<button></button><div>1</div><!--if-->`)
|
|
|
+ expect(newMountSpy).toHaveBeenCalledTimes(1)
|
|
|
+ expect(newActiveSpy).toHaveBeenCalledTimes(1)
|
|
|
+ expect(newDeactivatedSpy).toHaveBeenCalledTimes(0)
|
|
|
+
|
|
|
+ // subsequent toggles should use KeepAlive cache for the new instance
|
|
|
+ triggerEvent('click', root.children[0] as Element)
|
|
|
+ await nextTick()
|
|
|
+ expect(root.innerHTML).toBe(`<button></button><!--if-->`)
|
|
|
+ expect(newMountSpy).toHaveBeenCalledTimes(1)
|
|
|
+ expect(newActiveSpy).toHaveBeenCalledTimes(1)
|
|
|
+ expect(newDeactivatedSpy).toHaveBeenCalledTimes(1)
|
|
|
+
|
|
|
+ triggerEvent('click', root.children[0] as Element)
|
|
|
+ await nextTick()
|
|
|
+ expect(root.innerHTML).toBe(`<button></button><div>1</div><!--if-->`)
|
|
|
+ expect(newMountSpy).toHaveBeenCalledTimes(1)
|
|
|
+ expect(newActiveSpy).toHaveBeenCalledTimes(2)
|
|
|
+ expect(newDeactivatedSpy).toHaveBeenCalledTimes(1)
|
|
|
+ expect(newUnmountSpy).toHaveBeenCalledTimes(0)
|
|
|
+ })
|
|
|
+
|
|
|
test('reload KeepAlive slot in Transition', async () => {
|
|
|
const root = document.createElement('div')
|
|
|
document.body.appendChild(root)
|