]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-vapor): properly cache variable used in object property shorthand (...
authoredison <daiwei521@126.com>
Fri, 28 Feb 2025 09:02:52 +0000 (17:02 +0800)
committerGitHub <noreply@github.com>
Fri, 28 Feb 2025 09:02:52 +0000 (17:02 +0800)
packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/vBind.spec.ts
packages/compiler-vapor/src/generators/expression.ts

index 24585e39ea39dd949eaaf41aaa72eac69d369ef8..6e7d4229df8f766351f3a2726313f14e089e1828 100644 (file)
@@ -1,5 +1,20 @@
 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
+exports[`cache multiple access > cache variable used in both property shorthand and normal binding 1`] = `
+"import { setStyle as _setStyle, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
+const t0 = _template("<div></div>", true)
+
+export function render(_ctx) {
+  const n0 = t0()
+  _renderEffect(() => {
+    const _color = _ctx.color
+    _setStyle(n0, {color: _color})
+    _setProp(n0, "id", _color)
+  })
+  return n0
+}"
+`;
+
 exports[`cache multiple access > dynamic key bindings with expressions 1`] = `
 "import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue';
 const t0 = _template("<div></div>", true)
@@ -60,6 +75,17 @@ export function render(_ctx) {
 }"
 `;
 
+exports[`cache multiple access > not cache variable only used in property shorthand 1`] = `
+"import { setStyle as _setStyle, renderEffect as _renderEffect, template as _template } from 'vue';
+const t0 = _template("<div></div>", true)
+
+export function render(_ctx) {
+  const n0 = t0()
+  _renderEffect(() => _setStyle(n0, {color: _ctx.color}))
+  return n0
+}"
+`;
+
 exports[`cache multiple access > object property chain access 1`] = `
 "import { setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
 const t0 = _template("<div></div>")
index 5025997e20a880006f88bd608472176f3af7fa19..9a5f6ab69710a78246e79696d4ac2ef279e6665b 100644 (file)
@@ -785,6 +785,23 @@ describe('cache multiple access', () => {
     expect(code).contains('_setProp(n0, "id", _obj[1][_ctx.baz] + _obj.bar)')
   })
 
+  test('cache variable used in both property shorthand and normal binding', () => {
+    const { code } = compileWithVBind(`
+        <div :style="{color}" :id="color"/>
+      `)
+    expect(code).matchSnapshot()
+    expect(code).contains('const _color = _ctx.color')
+    expect(code).contains('_setStyle(n0, {color: _color})')
+  })
+
+  test('not cache variable only used in property shorthand', () => {
+    const { code } = compileWithVBind(`
+        <div :style="{color}" />
+      `)
+    expect(code).matchSnapshot()
+    expect(code).not.contains('const _color = _ctx.color')
+  })
+
   test('not cache variable and member expression with the same name', () => {
     const { code } = compileWithVBind(`
         <div :id="bar + obj.bar"></div>
index e128ccfbe8520866d7875a6af594d227263ca9b8..eedaeeb380a9459fee7383626331cae270e2fa26 100644 (file)
@@ -131,7 +131,11 @@ function genIdentifier(
   if (idMap && idMap.length) {
     const replacement = idMap[0]
     if (isString(replacement)) {
-      return [[replacement, NewlineType.None, loc]]
+      if (parent && parent.type === 'ObjectProperty' && parent.shorthand) {
+        return [[`${name}: ${replacement}`, NewlineType.None, loc]]
+      } else {
+        return [[replacement, NewlineType.None, loc]]
+      }
     } else {
       // replacement is an expression - process it again
       return genExpression(replacement, context, assignment)
@@ -292,7 +296,7 @@ function analyzeExpressions(expressions: SimpleExpressionNode[]) {
     }
 
     walk(exp.ast, {
-      enter(currentNode: Node) {
+      enter(currentNode: Node, parent: Node | null) {
         if (currentNode.type === 'MemberExpression') {
           const memberExp = extractMemberExpression(
             currentNode,
@@ -304,6 +308,16 @@ function analyzeExpressions(expressions: SimpleExpressionNode[]) {
           return this.skip()
         }
 
+        // skip shorthand or non-computed property keys
+        if (
+          parent &&
+          parent.type === 'ObjectProperty' &&
+          parent.key === currentNode &&
+          (parent.shorthand || !parent.computed)
+        ) {
+          return this.skip()
+        }
+
         if (currentNode.type === 'Identifier') {
           registerVariable(currentNode.name, exp, true)
         }