]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: add more tests
authordaiwei <daiwei521@126.com>
Fri, 14 Mar 2025 03:44:04 +0000 (11:44 +0800)
committerdaiwei <daiwei521@126.com>
Fri, 14 Mar 2025 03:44:04 +0000 (11:44 +0800)
packages-private/vapor-e2e-test/__tests__/transition.spec.ts
packages-private/vapor-e2e-test/transition/App.vue
packages/runtime-vapor/src/component.ts
packages/runtime-vapor/src/components/Transition.ts
packages/runtime-vapor/src/components/TransitionGroup.ts

index 41d90104765bd82d791a00734b25fbe39802191d..891cf7791d669f2512d0a34bad0654006a74cc4b 100644 (file)
@@ -845,9 +845,60 @@ describe('vapor transition', () => {
       E2E_TIMEOUT,
     )
 
-    test.todo(
+    test(
       'transition + fallthrough attrs (in-out mode)',
-      async () => {},
+      async () => {
+        const btnSelector = '.if-fallthrough-attr-in-out > button'
+        const containerSelector = '.if-fallthrough-attr-in-out > div'
+
+        expect(await html(containerSelector)).toBe('<div foo="1">one</div>')
+
+        // toggle
+        await click(btnSelector)
+        await nextTick()
+        await transitionFinish(duration * 3)
+        let calls = await page().evaluate(() => {
+          return (window as any).getCalls('ifInOut')
+        })
+        expect(calls).toStrictEqual([
+          'beforeEnter',
+          'onEnter',
+          'afterEnter',
+          'beforeLeave',
+          'onLeave',
+          'afterLeave',
+        ])
+
+        expect(await html(containerSelector)).toBe(
+          '<div foo="1" class="">two</div>',
+        )
+
+        // clear calls
+        await page().evaluate(() => {
+          ;(window as any).resetCalls('ifInOut')
+        })
+
+        // toggle back
+        await click(btnSelector)
+        await nextTick()
+        await transitionFinish(duration * 3)
+
+        calls = await page().evaluate(() => {
+          return (window as any).getCalls('ifInOut')
+        })
+        expect(calls).toStrictEqual([
+          'beforeEnter',
+          'onEnter',
+          'afterEnter',
+          'beforeLeave',
+          'onLeave',
+          'afterLeave',
+        ])
+
+        expect(await html(containerSelector)).toBe(
+          '<div foo="1" class="">one</div>',
+        )
+      },
       E2E_TIMEOUT,
     )
   })
index 7a01e07f231cc9ab5927e44d5ecdb5bb42ce339a..1c73d7d8f9034a4a9ffa87699467d65f72f9ca4a 100644 (file)
@@ -21,6 +21,7 @@ let calls = {
   enterCancel: [],
   withAppear: [],
   cssFalse: [],
+  ifInOut: [],
 }
 window.getCalls = key => calls[key]
 window.resetCalls = key => (calls[key] = [])
@@ -73,6 +74,16 @@ const view = shallowRef(One)
 function changeView() {
   view.value = view.value === One ? Two : One
 }
+
+const SimpleOne = defineVaporComponent({
+  setup() {
+    return template('<div>one</div>', true)()
+  },
+})
+const viewInOut = shallowRef(SimpleOne)
+function changeViewInOut() {
+  viewInOut.value = viewInOut.value === SimpleOne ? Two : SimpleOne
+}
 </script>
 
 <template>
@@ -308,6 +319,24 @@ function changeView() {
       </div>
       <button @click="toggle = !toggle">button fallthrough</button>
     </div>
+    <div class="if-fallthrough-attr-in-out">
+      <div>
+        <transition
+          foo="1"
+          name="test"
+          mode="in-out"
+          @beforeEnter="() => calls.ifInOut.push('beforeEnter')"
+          @enter="() => calls.ifInOut.push('onEnter')"
+          @afterEnter="() => calls.ifInOut.push('afterEnter')"
+          @beforeLeave="() => calls.ifInOut.push('beforeLeave')"
+          @leave="() => calls.ifInOut.push('onLeave')"
+          @afterLeave="() => calls.ifInOut.push('afterLeave')"
+        >
+          <component :is="viewInOut"></component>
+        </transition>
+      </div>
+      <button @click="changeViewInOut">button</button>
+    </div>
 
     <div class="vshow">
       <button @click="show = !show">Show</button>
index 78f13d5966a3ddd9fbeb95877bf035587d881820..ae0f2549797381313e7a37fc2c30c4d538f97cc7 100644 (file)
@@ -236,11 +236,9 @@ export function createComponent(
     instance.block instanceof Element &&
     Object.keys(instance.attrs).length
   ) {
-    renderEffect(() => {
-      isApplyingFallthroughProps = true
-      setDynamicProps(instance.block as Element, [instance.attrs])
-      isApplyingFallthroughProps = false
-    })
+    renderEffect(() =>
+      applyFallthroughProps(instance.block as Element, instance.attrs),
+    )
   }
 
   resetTracking()
@@ -258,6 +256,15 @@ export function createComponent(
 
 export let isApplyingFallthroughProps = false
 
+export function applyFallthroughProps(
+  block: Block,
+  attrs: Record<string, any>,
+): void {
+  isApplyingFallthroughProps = true
+  setDynamicProps(block as Element, [attrs])
+  isApplyingFallthroughProps = false
+}
+
 /**
  * dev only
  */
index 7f6179a3a7a1406d43490b86c54af94f1c75b7d6..73cf570fc6902ec32c423f280a3b4a5cfc5578e6 100644 (file)
@@ -21,10 +21,13 @@ import {
   type VaporTransitionHooks,
   isFragment,
 } from '../block'
-import { type VaporComponentInstance, isVaporComponent } from '../component'
+import {
+  type VaporComponentInstance,
+  applyFallthroughProps,
+  isVaporComponent,
+} from '../component'
 import { extend, isArray } from '@vue/shared'
 import { renderEffect } from '../renderEffect'
-import { setDynamicProps } from '../dom/prop'
 
 const decorate = (t: typeof VaporTransition) => {
   t.displayName = 'VaporTransition'
@@ -71,7 +74,7 @@ export const VaporTransition: FunctionalComponent<TransitionProps> =
         const resolvedAttrs = extend({}, attrs)
         const child = findTransitionBlock(children)
         if (child) {
-          setDynamicProps(child, [resolvedAttrs])
+          applyFallthroughProps(child, resolvedAttrs)
           // ensure fallthrough attrs are not happened again in
           // applyTransitionHooks
           fallthroughAttrs = false
@@ -185,7 +188,7 @@ export function applyTransitionHooks(
 
   // fallthrough attrs
   if (fallthroughAttrs && instance.hasFallthrough) {
-    setDynamicProps(child, [instance.attrs])
+    applyFallthroughProps(child, instance.attrs)
   }
 
   return resolvedHooks
@@ -256,7 +259,8 @@ export function findTransitionBlock(
     if (block instanceof Element) child = block
   } else if (isVaporComponent(block)) {
     child = findTransitionBlock(block.block)
-    if (child && child.$key === undefined) child.$key = block.type.__name
+    // use component id as key
+    if (child && child.$key === undefined) child.$key = block.uid
   } else if (isArray(block)) {
     child = block[0] as TransitionBlock
     let hasFound = false
index c12260bf37b9097d7ada7aaad889525cd36782ea..af8c8300f7615666c0e9671cfce3d647128c4118 100644 (file)
@@ -31,10 +31,11 @@ import {
 import {
   type ObjectVaporComponent,
   type VaporComponentInstance,
+  applyFallthroughProps,
   isVaporComponent,
 } from '../component'
 import { isForBlock } from '../apiCreateFor'
-import { renderEffect, setDynamicProps } from '@vue/runtime-vapor'
+import { renderEffect } from '../renderEffect'
 
 const positionMap = new WeakMap<TransitionBlock, DOMRect>()
 const newPositionMap = new WeakMap<TransitionBlock, DOMRect>()
@@ -149,7 +150,7 @@ export const VaporTransitionGroup: ObjectVaporComponent = decorate({
       insert(slottedBlock, container)
       // fallthrough attrs
       if (instance!.hasFallthrough) {
-        renderEffect(() => setDynamicProps(container, [instance!.attrs]))
+        renderEffect(() => applyFallthroughProps(container, instance!.attrs))
       }
       return container
     } else {