]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): fix v-bind shorthand for component :is
authorEvan You <yyx990803@gmail.com>
Mon, 15 Apr 2024 09:36:05 +0000 (17:36 +0800)
committerEvan You <yyx990803@gmail.com>
Mon, 15 Apr 2024 09:36:05 +0000 (17:36 +0800)
close #10469
close #10471

packages/compiler-core/__tests__/transforms/transformElement.spec.ts
packages/compiler-core/src/transforms/transformElement.ts

index 5d3f92ced181e97403c3eff16fb5263d4d2988c9..c30840a21a648b7b4e4ff774834d6fc186fae892 100644 (file)
@@ -1231,6 +1231,24 @@ describe('compiler: element transform', () => {
       })
     })
 
+    test('dynamic binding shorthand', () => {
+      const { node, root } = parseWithBind(`<component :is />`)
+      expect(root.helpers).toContain(RESOLVE_DYNAMIC_COMPONENT)
+      expect(node).toMatchObject({
+        isBlock: true,
+        tag: {
+          callee: RESOLVE_DYNAMIC_COMPONENT,
+          arguments: [
+            {
+              type: NodeTypes.SIMPLE_EXPRESSION,
+              content: 'is',
+              isStatic: false,
+            },
+          ],
+        },
+      })
+    })
+
     test('is casting', () => {
       const { node, root } = parseWithBind(`<div is="vue:foo" />`)
       expect(root.helpers).toContain(RESOLVE_COMPONENT)
index c50f7f5e96933ee61a6ea79748a6926d4b3823df..ca6e59df32bc4debcc7e28efa1785b2ca95c37b8 100644 (file)
@@ -64,6 +64,7 @@ import {
   checkCompatEnabled,
   isCompatEnabled,
 } from '../compat/compatConfig'
+import { processExpression } from './transformExpression'
 
 // some directive transforms (e.g. v-model) may return a symbol for runtime
 // import, which should be used instead of a resolveDirective call.
@@ -253,7 +254,7 @@ export function resolveComponentType(
 
   // 1. dynamic component
   const isExplicitDynamic = isComponentTag(tag)
-  const isProp = findProp(node, 'is')
+  const isProp = findProp(node, 'is', false, true /* allow empty */)
   if (isProp) {
     if (
       isExplicitDynamic ||
@@ -263,10 +264,19 @@ export function resolveComponentType(
           context,
         ))
     ) {
-      const exp =
-        isProp.type === NodeTypes.ATTRIBUTE
-          ? isProp.value && createSimpleExpression(isProp.value.content, true)
-          : isProp.exp
+      let exp: ExpressionNode | undefined
+      if (isProp.type === NodeTypes.ATTRIBUTE) {
+        exp = isProp.value && createSimpleExpression(isProp.value.content, true)
+      } else {
+        exp = isProp.exp
+        if (!exp) {
+          // #10469 handle :is shorthand
+          exp = createSimpleExpression(`is`, false, isProp.loc)
+          if (!__BROWSER__) {
+            exp = isProp.exp = processExpression(exp, context)
+          }
+        }
+      }
       if (exp) {
         return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
           exp,