From 48a1370405abfcb1258e4e4cf7ea247cfba5a5a9 Mon Sep 17 00:00:00 2001 From: edison Date: Thu, 26 Jun 2025 14:44:39 +0800 Subject: [PATCH] fix(compiler-vapor): properly cache variable with optional chaining (#13519) --- .../transforms/__snapshots__/vBind.spec.ts.snap | 14 ++++++++++++++ .../__tests__/transforms/vBind.spec.ts | 7 +++++++ .../compiler-vapor/src/generators/expression.ts | 1 + 3 files changed, 22 insertions(+) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap index 4e34c1818..62a68ca42 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -113,6 +113,20 @@ export function render(_ctx) { }" `; +exports[`cache multiple access > optional chaining 1`] = ` +"import { setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue'; +const t0 = _template("
", true) + +export function render(_ctx) { + const n0 = t0() + _renderEffect(() => { + const _obj = _ctx.obj + _setProp(n0, "id", _obj?.foo + _obj?.bar) + }) + return n0 +}" +`; + exports[`cache multiple access > repeated expression in expressions 1`] = ` "import { setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 60c3ebf0c..c062c96ba 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -794,6 +794,13 @@ describe('cache multiple access', () => { expect(code).contains('_setStyle(n0, {color: _color})') }) + test('optional chaining', () => { + const { code } = compileWithVBind(`
`) + expect(code).matchSnapshot() + expect(code).contains('const _obj = _ctx.obj') + expect(code).contains('_setProp(n0, "id", _obj?.foo + _obj?.bar)') + }) + test('not cache variable only used in property shorthand', () => { const { code } = compileWithVBind(`
diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index 845c8bedd..e2c3c0e17 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -588,6 +588,7 @@ function extractMemberExpression( case 'CallExpression': // foo[bar(baz)] return `${extractMemberExpression(exp.callee, onIdentifier)}(${exp.arguments.map(arg => extractMemberExpression(arg, onIdentifier)).join(', ')})` case 'MemberExpression': // foo[bar.baz] + case 'OptionalMemberExpression': // foo?.bar const object = extractMemberExpression(exp.object, onIdentifier) const prop = exp.computed ? `[${extractMemberExpression(exp.property, onIdentifier)}]`