Explorar el Código

fix(compiler-core/v-on): handle falsy values when caching v-on handlers

fix #2605
Evan You hace 5 años
padre
commit
e4f09c1419

+ 41 - 1
packages/compiler-core/__tests__/transforms/vOn.spec.ts

@@ -476,7 +476,47 @@ describe('compiler: transform v-on', () => {
         index: 1,
         value: {
           type: NodeTypes.COMPOUND_EXPRESSION,
-          children: [`(...args) => (`, { content: `_ctx.foo(...args)` }, `)`]
+          children: [
+            `(...args) => (`,
+            { content: `_ctx.foo && _ctx.foo(...args)` },
+            `)`
+          ]
+        }
+      })
+    })
+
+    test('compound member expression handler', () => {
+      const { root, node } = parseWithVOn(`<div v-on:click="foo.bar" />`, {
+        prefixIdentifiers: true,
+        cacheHandlers: true
+      })
+      expect(root.cached).toBe(1)
+      const vnodeCall = node.codegenNode as VNodeCall
+      // should not treat cached handler as dynamicProp, so no flags
+      expect(vnodeCall.patchFlag).toBeUndefined()
+      expect(
+        (vnodeCall.props as ObjectExpression).properties[0].value
+      ).toMatchObject({
+        type: NodeTypes.JS_CACHE_EXPRESSION,
+        index: 1,
+        value: {
+          type: NodeTypes.COMPOUND_EXPRESSION,
+          children: [
+            `(...args) => (`,
+            {
+              children: [
+                { content: `_ctx.foo` },
+                `.`,
+                { content: `bar` },
+                ` && `,
+                { content: `_ctx.foo` },
+                `.`,
+                { content: `bar` },
+                `(...args)`
+              ]
+            },
+            `)`
+          ]
         }
       })
     })

+ 2 - 2
packages/compiler-core/src/transforms/vOn.ts

@@ -108,9 +108,9 @@ export const transformOn: DirectiveTransform = (
       // avoiding the need to be patched.
       if (shouldCache && isMemberExp) {
         if (exp.type === NodeTypes.SIMPLE_EXPRESSION) {
-          exp.content += `(...args)`
+          exp.content = `${exp.content} && ${exp.content}(...args)`
         } else {
-          exp.children.push(`(...args)`)
+          exp.children = [...exp.children, ` && `, ...exp.children, `(...args)`]
         }
       }
     }