]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: add TransformTransition
authordaiwei <daiwei521@126.com>
Fri, 7 Mar 2025 14:17:19 +0000 (22:17 +0800)
committerdaiwei <daiwei521@126.com>
Fri, 7 Mar 2025 14:17:19 +0000 (22:17 +0800)
packages/compiler-dom/src/index.ts
packages/compiler-dom/src/transforms/Transition.ts
packages/compiler-vapor/__tests__/transforms/TransformTransition.spec.ts
packages/compiler-vapor/__tests__/transforms/__snapshots__/TransformTransition.spec.ts.snap
packages/compiler-vapor/src/compile.ts
packages/compiler-vapor/src/transforms/transformTransition.ts [new file with mode: 0644]

index 950901e7bf91c1d6ad97f8526ff788f538658adc..446a917ad7c51aad871475715bd1d910e8a06a51 100644 (file)
@@ -76,4 +76,5 @@ export {
 } from './errors'
 export { resolveModifiers } from './transforms/vOn'
 export { isValidHTMLNesting } from './htmlNesting'
+export { postTransformTransition } from './transforms/Transition'
 export * from '@vue/compiler-core'
index f6cf968e37263492a9348f7a9afcca03684a6948..85f83adc751805e2b6d1d16845edd36c49f18ebf 100644 (file)
@@ -1,4 +1,5 @@
 import {
+  type CompilerError,
   type ComponentNode,
   ElementTypes,
   type IfBranchNode,
@@ -15,40 +16,43 @@ export const transformTransition: NodeTransform = (node, context) => {
   ) {
     const component = context.isBuiltInComponent(node.tag)
     if (component === TRANSITION) {
-      return () => {
-        if (!node.children.length) {
-          return
-        }
+      return postTransformTransition(node, context.onError)
+    }
+  }
+}
 
-        // warn multiple transition children
-        if (hasMultipleChildren(node)) {
-          context.onError(
-            createDOMCompilerError(
-              DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN,
-              {
-                start: node.children[0].loc.start,
-                end: node.children[node.children.length - 1].loc.end,
-                source: '',
-              },
-            ),
-          )
-        }
+export function postTransformTransition(
+  node: ComponentNode,
+  onError: (error: CompilerError) => void,
+): () => void {
+  return () => {
+    if (!node.children.length) {
+      return
+    }
+
+    if (hasMultipleChildren(node)) {
+      onError(
+        createDOMCompilerError(DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN, {
+          start: node.children[0].loc.start,
+          end: node.children[node.children.length - 1].loc.end,
+          source: '',
+        }),
+      )
+    }
 
-        // check if it's s single child w/ v-show
-        // if yes, inject "persisted: true" to the transition props
-        const child = node.children[0]
-        if (child.type === NodeTypes.ELEMENT) {
-          for (const p of child.props) {
-            if (p.type === NodeTypes.DIRECTIVE && p.name === 'show') {
-              node.props.push({
-                type: NodeTypes.ATTRIBUTE,
-                name: 'persisted',
-                nameLoc: node.loc,
-                value: undefined,
-                loc: node.loc,
-              })
-            }
-          }
+    // check if it's s single child w/ v-show
+    // if yes, inject "persisted: true" to the transition props
+    const child = node.children[0]
+    if (child.type === NodeTypes.ELEMENT) {
+      for (const p of child.props) {
+        if (p.type === NodeTypes.DIRECTIVE && p.name === 'show') {
+          node.props.push({
+            type: NodeTypes.ATTRIBUTE,
+            name: 'persisted',
+            nameLoc: node.loc,
+            value: undefined,
+            loc: node.loc,
+          })
         }
       }
     }
index 3fbabe7337bec846c7219171e634e6db2db68ab1..846179f879d56e408a34662f5adbb9a99e82f936 100644 (file)
@@ -5,9 +5,11 @@ import {
   transformText,
   transformVBind,
   transformVIf,
+  transformVShow,
   transformVSlot,
 } from '@vue/compiler-vapor'
-import { expect } from 'vitest'
+import { transformTransition } from '../../src/transforms/transformTransition'
+import { DOMErrorCodes } from '@vue/compiler-dom'
 
 const compileWithElementTransform = makeCompile({
   nodeTransforms: [
@@ -16,9 +18,11 @@ const compileWithElementTransform = makeCompile({
     transformElement,
     transformVSlot,
     transformChildren,
+    transformTransition,
   ],
   directiveTransforms: {
     bind: transformVBind,
+    show: transformVShow,
   },
 })
 
@@ -52,4 +56,33 @@ describe('compiler: transition', () => {
     // should preserve key
     expect(code).contains('n0.$key = _ctx.key')
   })
+
+  test('warns if multiple children', () => {
+    const onError = vi.fn()
+    compileWithElementTransform(
+      `<Transition>
+        <h1>foo</h1>
+        <h2>bar</h2>
+      </Transition>`,
+      {
+        onError,
+      },
+    )
+    expect(onError).toHaveBeenCalled()
+    expect(onError.mock.calls).toMatchObject([
+      [{ code: DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN }],
+    ])
+  })
+
+  test('inject persisted when child has v-show', () => {
+    expect(
+      compileWithElementTransform(`
+        <Transition>
+          <div v-show="ok" />
+        </Transition>
+    `).code,
+    ).toMatchSnapshot()
+  })
+
+  // TODO more tests
 })
index dd33a4ddf25d468a318280f43d2238d3afcd1890..4264677c7c407e00c20f7b83053f1ddb75623d15 100644 (file)
@@ -1,13 +1,33 @@
 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
 exports[`compiler: transition > basic 1`] = `
-"import { VaporTransition as _VaporTransition, createComponent as _createComponent, template as _template } from 'vue';
+"import { VaporTransition as _VaporTransition, applyVShow as _applyVShow, createComponent as _createComponent, template as _template } from 'vue';
 const t0 = _template("<h1>foo</h1>")
 
 export function render(_ctx) {
-  const n1 = _createComponent(_VaporTransition, { appear: () => ("") }, {
+  const n1 = _createComponent(_VaporTransition, {
+    appear: () => (""), 
+    persisted: () => ("")
+  }, {
     "default": () => {
       const n0 = t0()
+      _applyVShow(n0, () => (_ctx.show))
+      return n0
+    }
+  }, true)
+  return n1
+}"
+`;
+
+exports[`compiler: transition > inject persisted when child has v-show 1`] = `
+"import { VaporTransition as _VaporTransition, applyVShow as _applyVShow, createComponent as _createComponent, template as _template } from 'vue';
+const t0 = _template("<div></div>")
+
+export function render(_ctx) {
+  const n1 = _createComponent(_VaporTransition, { persisted: () => ("") }, {
+    "default": () => {
+      const n0 = t0()
+      _applyVShow(n0, () => (_ctx.ok))
       return n0
     }
   }, true)
index f84eafcbe0bfc9b0fe3e2c98071ca7f56f7ad5a7..04dd6543d61659f0dc7f0d147b39c6363bd1c0ab 100644 (file)
@@ -26,6 +26,7 @@ import { transformVFor } from './transforms/vFor'
 import { transformComment } from './transforms/transformComment'
 import { transformSlotOutlet } from './transforms/transformSlotOutlet'
 import { transformVSlot } from './transforms/vSlot'
+import { transformTransition } from './transforms/transformTransition'
 import type { HackOptions } from './ir'
 
 export { wrapTemplate } from './transforms/utils'
@@ -54,6 +55,7 @@ export function compile(
     extend({}, resolvedOptions, {
       nodeTransforms: [
         ...nodeTransforms,
+        ...(__DEV__ ? [transformTransition] : []),
         ...(options.nodeTransforms || []), // user transforms
       ],
       directiveTransforms: extend(
diff --git a/packages/compiler-vapor/src/transforms/transformTransition.ts b/packages/compiler-vapor/src/transforms/transformTransition.ts
new file mode 100644 (file)
index 0000000..918666d
--- /dev/null
@@ -0,0 +1,15 @@
+import type { NodeTransform } from '@vue/compiler-vapor'
+import { ElementTypes, NodeTypes } from '@vue/compiler-core'
+import { isTransitionTag } from '../utils'
+import { postTransformTransition } from '@vue/compiler-dom'
+
+export const transformTransition: NodeTransform = (node, context) => {
+  if (
+    node.type === NodeTypes.ELEMENT &&
+    node.tagType === ElementTypes.COMPONENT
+  ) {
+    if (isTransitionTag(node.tag)) {
+      return postTransformTransition(node, context.options.onError)
+    }
+  }
+}