+++ /dev/null
-import path from 'node:path'
-import {
- E2E_TIMEOUT,
- setupPuppeteer,
-} from '../../../packages/vue/__tests__/e2e/e2eUtils'
-import connect from 'connect'
-import sirv from 'sirv'
-const { page, html, click, value, enterValue } = setupPuppeteer()
-
-describe('vapor keepalive', () => {
- let server: any
- const port = '8197'
- beforeAll(() => {
- server = connect()
- .use(sirv(path.resolve(import.meta.dirname, '../dist')))
- .listen(port)
- process.on('SIGTERM', () => server && server.close())
- })
-
- beforeEach(async () => {
- const baseUrl = `http://localhost:${port}/keepalive/`
- await page().goto(baseUrl)
- await page().waitForSelector('#app')
- })
-
- afterAll(() => {
- server.close()
- })
-
- test(
- 'render vdom component',
- async () => {
- const testSelector = '.render-vdom-component'
- const btnShow = `${testSelector} .btn-show`
- const btnToggle = `${testSelector} .btn-toggle`
- const container = `${testSelector} > div`
- const inputSelector = `${testSelector} input`
-
- let calls = await page().evaluate(() => {
- return (window as any).getCalls()
- })
- expect(calls).toStrictEqual(['mounted', 'activated'])
-
- expect(await html(container)).toBe('<input type="text">')
- expect(await value(inputSelector)).toBe('vdom')
-
- // change input value
- await enterValue(inputSelector, 'changed')
- expect(await value(inputSelector)).toBe('changed')
-
- // deactivate
- await click(btnToggle)
- expect(await html(container)).toBe('')
- calls = await page().evaluate(() => {
- return (window as any).getCalls()
- })
- expect(calls).toStrictEqual(['deactivated'])
-
- // activate
- await click(btnToggle)
- expect(await html(container)).toBe('<input type="text">')
- expect(await value(inputSelector)).toBe('changed')
- calls = await page().evaluate(() => {
- return (window as any).getCalls()
- })
- expect(calls).toStrictEqual(['activated'])
-
- // unmount keepalive
- await click(btnShow)
- expect(await html(container)).toBe('')
- calls = await page().evaluate(() => {
- return (window as any).getCalls()
- })
- expect(calls).toStrictEqual(['deactivated', 'unmounted'])
-
- // mount keepalive
- await click(btnShow)
- expect(await html(container)).toBe('<input type="text">')
- expect(await value(inputSelector)).toBe('vdom')
- calls = await page().evaluate(() => {
- return (window as any).getCalls()
- })
- expect(calls).toStrictEqual(['mounted', 'activated'])
- },
- E2E_TIMEOUT,
- )
-})
<a href="/interop/">VDOM / Vapor interop</a>
<a href="/todomvc/">Vapor TodoMVC</a>
-<a href="/keepalive/">Vapor KeepAlive</a>
<a href="/transition/">Vapor Transition</a>
<a href="/transition-group/">Vapor TransitionGroup</a>
display: block;
margin: 10px;
}
-</style>
+</style>
\ No newline at end of file
+++ /dev/null
-<script vapor>
-import { ref } from 'vue'
-import VdomComp from './components/VdomComp.vue'
-
-window.calls = []
-window.getCalls = () => {
- const ret = window.calls.slice()
- window.calls = []
- return ret
-}
-
-const show = ref(true)
-const toggle = ref(true)
-</script>
-
-<template>
- <div class="render-vdom-component">
- <button class="btn-show" @click="show = !show">show</button>
- <button class="btn-toggle" @click="toggle = !toggle">toggle</button>
- <div>
- <KeepAlive v-if="show">
- <VdomComp v-if="toggle"></VdomComp>
- </KeepAlive>
- </div>
- </div>
-</template>
+++ /dev/null
-<script setup>
-import { onActivated, onDeactivated, onMounted, onUnmounted, ref } from 'vue'
-const msg = ref('vdom')
-
-onMounted(() => {
- window.calls.push('mounted')
-})
-onActivated(() => {
- window.calls.push('activated')
-})
-onDeactivated(() => {
- window.calls.push('deactivated')
-})
-onUnmounted(() => {
- window.calls.push('unmounted')
-})
-</script>
-<template>
- <input type="text" v-model="msg" />
-</template>
+++ /dev/null
-<script type="module" src="./main.ts"></script>
-<div id="app"></div>
+++ /dev/null
-import { createVaporApp, vaporInteropPlugin } from 'vue'
-import App from './App.vue'
-
-createVaporApp(App).use(vaporInteropPlugin).mount('#app')
input: {
interop: resolve(import.meta.dirname, 'interop/index.html'),
todomvc: resolve(import.meta.dirname, 'todomvc/index.html'),
- keepalive: resolve(import.meta.dirname, 'keepalive/index.html'),
transition: resolve(import.meta.dirname, 'transition/index.html'),
transitionGroup: resolve(
import.meta.dirname,
import {
+ h,
nextTick,
onActivated,
onBeforeMount,
reactive,
ref,
shallowRef,
+ vModelText,
+ withDirectives,
} from 'vue'
import type { LooseRawProps, VaporComponent } from '../../src/component'
import { makeRender } from '../_utils'
createDynamicComponent,
createIf,
createTemplateRefSetter,
+ createVaporApp,
defineVaporComponent,
renderEffect,
setText,
template,
+ vaporInteropPlugin,
} from '../../src'
const define = makeRender()
expect(deactivatedHome).toHaveBeenCalledTimes(0)
expect(unmountedHome).toHaveBeenCalledTimes(1)
})
+
+ describe('vdom interop', () => {
+ test('render vdom component', async () => {
+ const VdomComp = {
+ setup() {
+ const msg = ref('vdom')
+ onBeforeMount(() => oneHooks.beforeMount())
+ onMounted(() => oneHooks.mounted())
+ onActivated(() => oneHooks.activated())
+ onDeactivated(() => oneHooks.deactivated())
+ onUnmounted(() => oneHooks.unmounted())
+ return () => {
+ return withDirectives(
+ h(
+ 'input',
+ {
+ type: 'text',
+ 'onUpdate:modelValue': ($event: any) => (msg.value = $event),
+ },
+ [],
+ ),
+ [[vModelText, msg.value]],
+ )
+ }
+ },
+ }
+
+ const show = ref(true)
+ const toggle = ref(true)
+
+ const App = defineVaporComponent({
+ setup() {
+ const n0 = createIf(
+ () => show.value,
+ () => {
+ const n5 = createComponent(
+ VaporKeepAlive,
+ null,
+ {
+ default: () => {
+ const n2 = createIf(
+ () => toggle.value,
+ () => {
+ const n4 = createComponent(VdomComp)
+ return n4
+ },
+ )
+ return n2
+ },
+ },
+ true,
+ )
+ return n5
+ },
+ )
+ return n0
+ },
+ })
+
+ const container = document.createElement('div')
+ document.body.appendChild(container)
+ const app = createVaporApp(App)
+ app.use(vaporInteropPlugin)
+ app.mount(container)
+
+ expect(container.innerHTML).toBe(`<input type="text"><!--if--><!--if-->`)
+ assertHookCalls(oneHooks, [1, 1, 1, 0, 0])
+
+ let inputEl = container.firstChild as HTMLInputElement
+ expect(inputEl.value).toBe('vdom')
+
+ inputEl.value = 'changed'
+ inputEl.dispatchEvent(new Event('input'))
+ await nextTick()
+
+ // deactivate
+ toggle.value = false
+ await nextTick()
+ expect(container.innerHTML).toBe(`<!--if--><!--if-->`)
+ assertHookCalls(oneHooks, [1, 1, 1, 1, 0])
+
+ // activate
+ toggle.value = true
+ await nextTick()
+ expect(container.innerHTML).toBe(`<input type="text"><!--if--><!--if-->`)
+ assertHookCalls(oneHooks, [1, 1, 2, 1, 0])
+ expect(inputEl.value).toBe('changed')
+
+ // unmount keepalive
+ show.value = false
+ await nextTick()
+ expect(container.innerHTML).toBe(`<!--if-->`)
+ assertHookCalls(oneHooks, [1, 1, 2, 2, 1])
+
+ // mount keepalive
+ show.value = true
+ await nextTick()
+ expect(container.innerHTML).toBe(`<input type="text"><!--if--><!--if-->`)
+ assertHookCalls(oneHooks, [2, 2, 3, 2, 1])
+ inputEl = container.firstChild as HTMLInputElement
+ expect(inputEl.value).toBe('vdom')
+ })
+ })
})