From: Evan You Date: Mon, 16 Aug 2021 19:57:10 +0000 (-0400) Subject: fix(compiler-core): fix hoisting logic for elements with cached handlers + other... X-Git-Tag: v3.2.3~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6c1db2728cd3c72b897cb7b245d532e63485b07;p=thirdparty%2Fvuejs%2Fcore.git fix(compiler-core): fix hoisting logic for elements with cached handlers + other bindings fix #4327 --- diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap index 0a6ca23220..73c714d837 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap @@ -211,6 +211,21 @@ return function render(_ctx, _cache) { }" `; +exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist elements with cached handlers + other bindings 1`] = ` +"import { normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\" + +export function render(_ctx, _cache) { + return (_openBlock(), _createElementBlock(\\"div\\", null, [ + _createElementVNode(\\"div\\", null, [ + _createElementVNode(\\"div\\", { + class: _normalizeClass({}), + onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.foo && _ctx.foo(...args))) + }) + ]) + ])) +}" +`; + exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist elements with cached handlers 1`] = ` "import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\" diff --git a/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts b/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts index e21fe7459c..0cbd4910a3 100644 --- a/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts +++ b/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts @@ -590,6 +590,25 @@ describe('compiler: hoistStatic transform', () => { ).toMatchSnapshot() }) + test('should NOT hoist elements with cached handlers + other bindings', () => { + const root = transformWithHoist( + `
`, + { + prefixIdentifiers: true, + cacheHandlers: true + } + ) + + expect(root.cached).toBe(1) + expect(root.hoists.length).toBe(0) + expect( + generate(root, { + mode: 'module', + prefixIdentifiers: true + }).code + ).toMatchSnapshot() + }) + test('should NOT hoist keyed template v-for with plain element child', () => { const root = transformWithHoist( `
` diff --git a/packages/compiler-core/src/transforms/hoistStatic.ts b/packages/compiler-core/src/transforms/hoistStatic.ts index 1ea895aced..27cc017a93 100644 --- a/packages/compiler-core/src/transforms/hoistStatic.ts +++ b/packages/compiler-core/src/transforms/hoistStatic.ts @@ -335,16 +335,17 @@ function getGeneratedPropsConstantType( if (keyType < returnType) { returnType = keyType } - if (value.type !== NodeTypes.SIMPLE_EXPRESSION) { + let valueType: ConstantTypes + if (value.type === NodeTypes.SIMPLE_EXPRESSION) { + valueType = getConstantType(value, context) + } else if (value.type === NodeTypes.JS_CALL_EXPRESSION) { // some helper calls can be hoisted, // such as the `normalizeProps` generated by the compiler for pre-normalize class, // in this case we need to respect the ConstanType of the helper's argments - if (value.type === NodeTypes.JS_CALL_EXPRESSION) { - return getConstantTypeOfHelperCall(value, context) - } - return ConstantTypes.NOT_CONSTANT + valueType = getConstantTypeOfHelperCall(value, context) + } else { + valueType = ConstantTypes.NOT_CONSTANT } - const valueType = getConstantType(value, context) if (valueType === ConstantTypes.NOT_CONSTANT) { return valueType }