]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test(vapor): useTemplateRef tests
authorEvan You <evan@vuejs.org>
Fri, 13 Dec 2024 01:37:49 +0000 (09:37 +0800)
committerEvan You <evan@vuejs.org>
Fri, 13 Dec 2024 01:37:49 +0000 (09:37 +0800)
packages/runtime-vapor/__tests__/dom/templateRef.spec.ts

index 1b912ed29304d90eb2fd0c125e401493a042540b..a9a116f8a5589ae307e52a54a54f417e1783fea4 100644 (file)
@@ -1,7 +1,9 @@
 import type { NodeRef } from '../../src/apiTemplateRef'
 import {
+  createComponent,
   createFor,
   createIf,
+  createSlot,
   createTemplateRefSetter,
   insert,
   renderEffect,
@@ -10,10 +12,12 @@ import {
 } from '../../src'
 import { makeRender } from '../_utils'
 import {
+  type ShallowRef,
   currentInstance,
   nextTick,
   reactive,
   ref,
+  useTemplateRef,
   watchEffect,
 } from '@vue/runtime-dom'
 
@@ -174,6 +178,57 @@ describe('api: template ref', () => {
     expect(fn.mock.calls[1][0]).toBe(undefined)
   })
 
+  test('useTemplateRef mount', () => {
+    const t0 = template('<div ref="refKey"></div>')
+    let r
+    let n
+    const { render } = define({
+      setup() {
+        r = useTemplateRef('foo')
+        n = t0()
+        createTemplateRefSetter()(n as Element, 'foo')
+        return n
+      },
+    })
+
+    const { host } = render()
+    expect(r!.value).toBe(host.children[0])
+  })
+
+  test('useTemplateRef update', async () => {
+    const t0 = template('<div></div>')
+    let fooEl: ShallowRef
+    let barEl: ShallowRef
+    const refKey = ref('foo')
+
+    const { render } = define({
+      setup() {
+        return {
+          foo: fooEl,
+          bar: barEl,
+        }
+      },
+      render() {
+        fooEl = useTemplateRef('foo')
+        barEl = useTemplateRef('bar')
+        const n0 = t0()
+        let r0: NodeRef | undefined
+        renderEffect(() => {
+          r0 = createTemplateRefSetter()(n0 as Element, refKey.value, r0)
+        })
+        return n0
+      },
+    })
+    const { host } = render()
+    expect(fooEl!.value).toBe(host.children[0])
+    expect(barEl!.value).toBe(null)
+
+    refKey.value = 'bar'
+    await nextTick()
+    expect(barEl!.value).toBe(host.children[0])
+    expect(fooEl!.value).toBe(null)
+  })
+
   it('should work with direct reactive property', () => {
     const state = reactive({
       refKey: null,
@@ -537,82 +592,95 @@ describe('api: template ref', () => {
     },
   )
 
-  // TODO: need to implement Component slots
-  // test('string ref inside slots', async () => {
-  //   const spy = vi.fn()
-  //   const { component: Child } = define({
-  //     render(this: any) {
-  //       return this.$slots.default()
-  //     },
-  //   })
-  //   const { render } = define({
-  //     render() {
-  //       onMounted(function (this: any) {
-  //         spy(this.$refs.foo.tag)
-  //       })
-  //       const n0 = createComponent(Child)
-  //       createTemplateRefSetter()(n0, 'foo')
-  //       return n0
-  //     },
-  //   })
-  //   const { host } = render()
+  test('string ref inside slots', () => {
+    const { component: Child } = define({
+      setup() {
+        return createSlot('default')
+      },
+    })
 
-  //   expect(spy).toHaveBeenCalledWith('div')
-  // })
+    const r = ref()
+    let n
+
+    const { render } = define({
+      setup() {
+        return {
+          foo: r,
+        }
+      },
+      render() {
+        const setRef = createTemplateRefSetter()
+        const n0 = createComponent(Child, null, {
+          default: () => {
+            n = document.createElement('div')
+            setRef(n, 'foo')
+            return n
+          },
+        })
+        return n0
+      },
+    })
 
-  //TODO: need setup return render function
-  // it('render function ref mount', () => {
-  //   const el = ref(null)
+    render()
+    expect(r.value).toBe(n)
+  })
 
-  //   const Comp = define({
-  //     setup() {
-  //       return () => h('div', { ref: el })
-  //     },
-  //   })
-  //   render(h(Comp), root)
-  //   expect(el.value).toBe(root.children[0])
-  // })
+  test('inline ref inside slots', () => {
+    const { component: Child } = define({
+      setup() {
+        return createSlot('default')
+      },
+    })
 
-  // it('render function ref update', async () => {
-  //   const root = nodeOps.createElement('div')
-  //   const refs = {
-  //     foo: ref(null),
-  //     bar: ref(null),
-  //   }
-  //   const refKey = ref<keyof typeof refs>('foo')
+    const r = ref()
+    let n
 
-  //   const Comp = {
-  //     setup() {
-  //       return () => h('div', { ref: refs[refKey.value] })
-  //     },
-  //   }
-  //   render(h(Comp), root)
-  //   expect(refs.foo.value).toBe(root.children[0])
-  //   expect(refs.bar.value).toBe(null)
+    const { render } = define({
+      setup() {
+        const setRef = createTemplateRefSetter()
+        const n0 = createComponent(Child, null, {
+          default: () => {
+            n = document.createElement('div')
+            setRef(n, r)
+            return n
+          },
+        })
+        return n0
+      },
+    })
 
-  //   refKey.value = 'bar'
-  //   await nextTick()
-  //   expect(refs.foo.value).toBe(null)
-  //   expect(refs.bar.value).toBe(root.children[0])
-  // })
+    render()
+    expect(r.value).toBe(n)
+  })
 
-  // it('render function ref unmount', async () => {
-  //   const root = nodeOps.createElement('div')
-  //   const el = ref(null)
-  //   const toggle = ref(true)
+  test('useTemplateRef ref inside slots', () => {
+    const { component: Child } = define({
+      setup() {
+        return createSlot('default')
+      },
+    })
 
-  //   const Comp = {
-  //     setup() {
-  //       return () => (toggle.value ? h('div', { ref: el }) : null)
-  //     },
-  //   }
-  //   render(h(Comp), root)
-  //   expect(el.value).toBe(root.children[0])
+    let r: ShallowRef
+    let n
 
-  //   toggle.value = false
-  //   await nextTick()
-  //   expect(el.value).toBe(null)
-  // })
+    const { render } = define({
+      setup() {
+        r = useTemplateRef('foo')
+        const setRef = createTemplateRefSetter()
+        const n0 = createComponent(Child, null, {
+          default: () => {
+            n = document.createElement('div')
+            setRef(n, 'foo')
+            return n
+          },
+        })
+        return n0
+      },
+    })
+
+    render()
+    expect(r!.value).toBe(n)
+  })
 
   // TODO: can not reproduce in Vapor
   // // #2078