|
|
@@ -8,11 +8,12 @@ import {
|
|
|
createSlot,
|
|
|
createTemplateRefSetter,
|
|
|
defineVaporComponent,
|
|
|
+ delegateEvents,
|
|
|
insert,
|
|
|
renderEffect,
|
|
|
template,
|
|
|
} from '../../src'
|
|
|
-import { makeRender } from '../_utils'
|
|
|
+import { compile, makeRender, runtimeDom, runtimeVapor } from '../_utils'
|
|
|
import {
|
|
|
type ShallowRef,
|
|
|
currentInstance,
|
|
|
@@ -794,3 +795,227 @@ describe('api: template ref', () => {
|
|
|
// expect(elRef1.value).toBe(elRef2.value)
|
|
|
// })
|
|
|
})
|
|
|
+
|
|
|
+describe('interop: template ref', () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ document.body.innerHTML = ''
|
|
|
+ })
|
|
|
+
|
|
|
+ const triggerEvent = (type: string, el: Element) => {
|
|
|
+ const event = new Event(type, { bubbles: true })
|
|
|
+ el.dispatchEvent(event)
|
|
|
+ }
|
|
|
+
|
|
|
+ delegateEvents('click')
|
|
|
+
|
|
|
+ async function testTemplateRefInterop(
|
|
|
+ code: string,
|
|
|
+ components: Record<string, { code: string; vapor: boolean }> = {},
|
|
|
+ data: any = {},
|
|
|
+ { vapor = false } = {},
|
|
|
+ ) {
|
|
|
+ const clientComponents: any = {}
|
|
|
+ for (const key in components) {
|
|
|
+ const comp = components[key]
|
|
|
+ const code = comp.code
|
|
|
+ const isVaporComp = !!comp.vapor
|
|
|
+ clientComponents[key] = compile(code, data, clientComponents, {
|
|
|
+ vapor: isVaporComp,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const clientComp = compile(code, data, clientComponents, {
|
|
|
+ vapor,
|
|
|
+ })
|
|
|
+
|
|
|
+ const app = (vapor ? runtimeVapor.createVaporApp : runtimeDom.createApp)(
|
|
|
+ clientComp,
|
|
|
+ )
|
|
|
+ app.use(runtimeVapor.vaporInteropPlugin)
|
|
|
+
|
|
|
+ const container = document.createElement('div')
|
|
|
+ document.body.appendChild(container)
|
|
|
+ app.mount(container)
|
|
|
+ return { container }
|
|
|
+ }
|
|
|
+
|
|
|
+ test('vdom app: useTemplateRef with vapor child', async () => {
|
|
|
+ const { container } = await testTemplateRefInterop(
|
|
|
+ `<script setup>
|
|
|
+ import { useTemplateRef } from 'vue'
|
|
|
+ const components = _components;
|
|
|
+ const elRef = useTemplateRef('el')
|
|
|
+ function click() {
|
|
|
+ elRef.value.change()
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+ <template>
|
|
|
+ <button class="btn" @click="click"></button>
|
|
|
+ <components.VaporChild ref="el"/>
|
|
|
+ </template>`,
|
|
|
+ {
|
|
|
+ VaporChild: {
|
|
|
+ code: `
|
|
|
+ <script vapor>
|
|
|
+ import { ref } from 'vue'
|
|
|
+ const msg = ref('foo')
|
|
|
+ function change(){
|
|
|
+ msg.value = 'bar'
|
|
|
+ }
|
|
|
+ defineExpose({ change })
|
|
|
+ </script>
|
|
|
+ <template><div>{{msg}}</div></template>
|
|
|
+ `,
|
|
|
+ vapor: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ )
|
|
|
+
|
|
|
+ expect(container.innerHTML).toBe(
|
|
|
+ `<button class="btn"></button><div>foo</div>`,
|
|
|
+ )
|
|
|
+
|
|
|
+ const btn = container.querySelector('.btn')
|
|
|
+ triggerEvent('click', btn!)
|
|
|
+ await nextTick()
|
|
|
+ expect(container.innerHTML).toBe(
|
|
|
+ `<button class="btn"></button><div>bar</div>`,
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ test('vdom app: static ref with vapor child', async () => {
|
|
|
+ const { container } = await testTemplateRefInterop(
|
|
|
+ `<script setup>
|
|
|
+ import { ref } from 'vue'
|
|
|
+ const components = _components;
|
|
|
+ const elRef = ref(null)
|
|
|
+ function click() {
|
|
|
+ elRef.value.change()
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+ <template>
|
|
|
+ <button class="btn" @click="click"></button>
|
|
|
+ <components.VaporChild ref="elRef"/>
|
|
|
+ </template>`,
|
|
|
+ {
|
|
|
+ VaporChild: {
|
|
|
+ code: `
|
|
|
+ <script vapor>
|
|
|
+ import { ref } from 'vue'
|
|
|
+ const msg = ref('foo')
|
|
|
+ function change(){
|
|
|
+ msg.value = 'bar'
|
|
|
+ }
|
|
|
+ defineExpose({ change })
|
|
|
+ </script>
|
|
|
+ <template><div>{{msg}}</div></template>
|
|
|
+ `,
|
|
|
+ vapor: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ )
|
|
|
+
|
|
|
+ expect(container.innerHTML).toBe(
|
|
|
+ `<button class="btn"></button><div>foo</div>`,
|
|
|
+ )
|
|
|
+
|
|
|
+ const btn = container.querySelector('.btn')
|
|
|
+ triggerEvent('click', btn!)
|
|
|
+ await nextTick()
|
|
|
+ expect(container.innerHTML).toBe(
|
|
|
+ `<button class="btn"></button><div>bar</div>`,
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ test('vapor app: useTemplateRef with vdom child', async () => {
|
|
|
+ const { container } = await testTemplateRefInterop(
|
|
|
+ `<script vapor>
|
|
|
+ import { useTemplateRef } from 'vue'
|
|
|
+ const components = _components;
|
|
|
+ const elRef = useTemplateRef('el')
|
|
|
+ function click() {
|
|
|
+ elRef.value.change()
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+ <template>
|
|
|
+ <button class="btn" @click="click"></button>
|
|
|
+ <components.VDOMChild ref="el"/>
|
|
|
+ </template>`,
|
|
|
+ {
|
|
|
+ VDOMChild: {
|
|
|
+ code: `
|
|
|
+ <script setup>
|
|
|
+ import { ref } from 'vue'
|
|
|
+ const msg = ref('foo')
|
|
|
+ function change(){
|
|
|
+ msg.value = 'bar'
|
|
|
+ }
|
|
|
+ defineExpose({ change })
|
|
|
+ </script>
|
|
|
+ <template><div>{{msg}}</div></template>
|
|
|
+ `,
|
|
|
+ vapor: false,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ undefined,
|
|
|
+ { vapor: true },
|
|
|
+ )
|
|
|
+
|
|
|
+ expect(container.innerHTML).toBe(
|
|
|
+ `<button class="btn"></button><div>foo</div>`,
|
|
|
+ )
|
|
|
+
|
|
|
+ const btn = container.querySelector('.btn')
|
|
|
+ triggerEvent('click', btn!)
|
|
|
+ await nextTick()
|
|
|
+ expect(container.innerHTML).toBe(
|
|
|
+ `<button class="btn"></button><div>bar</div>`,
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ test('vapor app: static ref with vdom child', async () => {
|
|
|
+ const { container } = await testTemplateRefInterop(
|
|
|
+ `<script vapor>
|
|
|
+ import { ref } from 'vue'
|
|
|
+ const components = _components;
|
|
|
+ const elRef = ref(null)
|
|
|
+ function click() {
|
|
|
+ elRef.value.change()
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+ <template>
|
|
|
+ <button class="btn" @click="click"></button>
|
|
|
+ <components.VDomChild ref="elRef"/>
|
|
|
+ </template>`,
|
|
|
+ {
|
|
|
+ VDomChild: {
|
|
|
+ code: `
|
|
|
+ <script setup>
|
|
|
+ import { ref } from 'vue'
|
|
|
+ const msg = ref('foo')
|
|
|
+ function change(){
|
|
|
+ msg.value = 'bar'
|
|
|
+ }
|
|
|
+ defineExpose({ change })
|
|
|
+ </script>
|
|
|
+ <template><div>{{msg}}</div></template>
|
|
|
+ `,
|
|
|
+ vapor: false,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ undefined,
|
|
|
+ { vapor: true },
|
|
|
+ )
|
|
|
+
|
|
|
+ expect(container.innerHTML).toBe(
|
|
|
+ `<button class="btn"></button><div>foo</div>`,
|
|
|
+ )
|
|
|
+
|
|
|
+ const btn = container.querySelector('.btn')
|
|
|
+ triggerEvent('click', btn!)
|
|
|
+ await nextTick()
|
|
|
+ expect(container.innerHTML).toBe(
|
|
|
+ `<button class="btn"></button><div>bar</div>`,
|
|
|
+ )
|
|
|
+ })
|
|
|
+})
|