Просмотр исходного кода

fix(compiler-core): fix v-bind shorthand handling for in-DOM templates (#13933)

close #13930
edison 5 месяцев назад
Родитель
Сommit
b3cca2611c

+ 21 - 0
packages/compiler-core/__tests__/transforms/vBind.spec.ts

@@ -112,6 +112,27 @@ describe('compiler: transform v-bind', () => {
     })
   })
 
+  test('no expression (shorthand) in-DOM templates', () => {
+    try {
+      __BROWSER__ = true
+      // :id in in-DOM templates will be parsed into :id="" by browser
+      const node = parseWithVBind(`<div :id="" />`)
+      const props = (node.codegenNode as VNodeCall).props as ObjectExpression
+      expect(props.properties[0]).toMatchObject({
+        key: {
+          content: `id`,
+          isStatic: true,
+        },
+        value: {
+          content: `id`,
+          isStatic: false,
+        },
+      })
+    } finally {
+      __BROWSER__ = false
+    }
+  })
+
   test('dynamic arg', () => {
     const node = parseWithVBind(`<div v-bind:[id]="id"/>`)
     const props = (node.codegenNode as VNodeCall).props as CallExpression

+ 1 - 1
packages/compiler-core/src/parser.ts

@@ -1054,7 +1054,7 @@ export function baseParse(input: string, options?: ParserOptions): RootNode {
         `[@vue/compiler-core] decodeEntities option is passed but will be ` +
           `ignored in non-browser builds.`,
       )
-    } else if (__BROWSER__ && !currentOptions.decodeEntities) {
+    } else if (__BROWSER__ && !__TEST__ && !currentOptions.decodeEntities) {
       throw new Error(
         `[@vue/compiler-core] decodeEntities option is required in browser builds.`,
       )

+ 5 - 1
packages/compiler-core/src/transforms/transformVBindShorthand.ts

@@ -15,7 +15,11 @@ export const transformVBindShorthand: NodeTransform = (node, context) => {
       if (
         prop.type === NodeTypes.DIRECTIVE &&
         prop.name === 'bind' &&
-        !prop.exp
+        (!prop.exp ||
+          // #13930 :foo in in-DOM templates will be parsed into :foo="" by browser
+          (__BROWSER__ &&
+            prop.exp.type === NodeTypes.SIMPLE_EXPRESSION &&
+            !prop.exp.content.trim()))
       ) {
         const arg = prop.arg!
         if (arg.type !== NodeTypes.SIMPLE_EXPRESSION || !arg.isStatic) {