Pārlūkot izejas kodu

fix(compiler-core): fix v-bind shorthand for component :is

close #10469
close #10471
Evan You 2 gadi atpakaļ
vecāks
revīzija
04af9504a7

+ 18 - 0
packages/compiler-core/__tests__/transforms/transformElement.spec.ts

@@ -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)

+ 15 - 5
packages/compiler-core/src/transforms/transformElement.ts

@@ -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,