Skip to content

fix(compiler-core): prefix key with v-memo outside v-for#14927

Closed
leno23 wants to merge 1 commit into
vuejs:mainfrom
leno23:fix-14920-v-memo-key-prefix
Closed

fix(compiler-core): prefix key with v-memo outside v-for#14927
leno23 wants to merge 1 commit into
vuejs:mainfrom
leno23:fix-14920-v-memo-key-prefix

Conversation

@leno23
Copy link
Copy Markdown
Contributor

@leno23 leno23 commented Jun 5, 2026

Fixes #14920.\n\nThis narrows the special-case skip for v-memo + :key expression processing to the scenario where v-for is also present. transformFor already processes that key expression eagerly, but plain elements with v-memo still need the normal transformExpression pass so identifiers are prefixed correctly.\n\nTest: pnpm vitest packages/compiler-core/tests/transforms/vMemo.spec.ts --run

Summary by CodeRabbit

  • Bug Fixes

    • Improved Vue compiler's treatment of v-memo directive when combined with v-for to correctly handle key binding processing, preventing unintended optimizations in these scenarios.
  • Tests

    • Added test coverage for v-memo directive with :key binding to ensure templates with this combination compile with the expected output structure.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 5, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c58786c7-f993-4efb-9400-9e8c29111376

📥 Commits

Reviewing files that changed from the base of the PR and between 9d92dbd and ad9c0cd.

📒 Files selected for processing (2)
  • packages/compiler-core/__tests__/transforms/vMemo.spec.ts
  • packages/compiler-core/src/transforms/transformExpression.ts

📝 Walkthrough

Walkthrough

This PR fixes a compiler bug where :key expressions on elements with v-memo directive (but without v-for) are not properly prefixed, causing runtime ReferenceErrors. The fix restricts the key-skip logic to require both v-memo and v-for, and adds a test case.

Changes

v-memo key expression prefixing fix

Layer / File(s) Summary
Fix key expression prefixing and add test case
packages/compiler-core/src/transforms/transformExpression.ts, packages/compiler-core/__tests__/transforms/vMemo.spec.ts
transformExpression now precomputes v-for presence and gates the "key already processed" skip condition by both memo && vFor instead of only memo. Test added for :key with v-memo on a plain element to verify the key expression is prefixed correctly.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • vuejs/core#14861: Directly related fix to the same v-memo/:key prefixing issue in vFor and v-memo directive handling.

Suggested labels

ready to merge, :hammer: p3-minor-bug, scope: compiler

Suggested reviewers

  • KazariEX
  • sxzz

Poem

A memo'd element, with a key to its name,
Once stumbled and crashed—a prefixing shame.
Now vFor guards the gate, the fix works just right,
Plain elements bind keys without a fright! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: addressing the v-memo and :key prefix issue specifically when v-for is absent.
Linked Issues check ✅ Passed The PR correctly fixes issue #14920 by narrowing the skip condition to only apply when both v-memo and v-for are present, ensuring :key expressions are prefixed on plain elements with v-memo.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the v-memo :key prefix issue: the test validates the fix and the transformExpression modification implements the required logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 5, 2026

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 106 kB 40.1 kB 36 kB
vue.global.prod.js 164 kB 60.1 kB 53.5 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 48.8 kB 19 kB 17.4 kB
createApp 56.9 kB 22 kB 20.1 kB
createSSRApp 61.2 kB 23.8 kB 21.7 kB
defineCustomElement 63.1 kB 23.9 kB 21.8 kB
overall 71.7 kB 27.4 kB 25 kB

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 5, 2026

Open in StackBlitz

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@14927
npm i https://pkg.pr.new/@vue/compiler-core@14927
yarn add https://pkg.pr.new/@vue/compiler-core@14927.tgz

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@14927
npm i https://pkg.pr.new/@vue/compiler-dom@14927
yarn add https://pkg.pr.new/@vue/compiler-dom@14927.tgz

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@14927
npm i https://pkg.pr.new/@vue/compiler-sfc@14927
yarn add https://pkg.pr.new/@vue/compiler-sfc@14927.tgz

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@14927
npm i https://pkg.pr.new/@vue/compiler-ssr@14927
yarn add https://pkg.pr.new/@vue/compiler-ssr@14927.tgz

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@14927
npm i https://pkg.pr.new/@vue/reactivity@14927
yarn add https://pkg.pr.new/@vue/reactivity@14927.tgz

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@14927
npm i https://pkg.pr.new/@vue/runtime-core@14927
yarn add https://pkg.pr.new/@vue/runtime-core@14927.tgz

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@14927
npm i https://pkg.pr.new/@vue/runtime-dom@14927
yarn add https://pkg.pr.new/@vue/runtime-dom@14927.tgz

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@14927
npm i https://pkg.pr.new/@vue/server-renderer@14927
yarn add https://pkg.pr.new/@vue/server-renderer@14927.tgz

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@14927
npm i https://pkg.pr.new/@vue/shared@14927
yarn add https://pkg.pr.new/@vue/shared@14927.tgz

vue

pnpm add https://pkg.pr.new/vue@14927
npm i https://pkg.pr.new/vue@14927
yarn add https://pkg.pr.new/vue@14927.tgz

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@14927
npm i https://pkg.pr.new/@vue/compat@14927
yarn add https://pkg.pr.new/@vue/compat@14927.tgz

commit: ad9c0cd

@leno23 leno23 marked this pull request as ready for review June 5, 2026 09:12
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad9c0cdd54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// key has been processed in transformFor(vMemo + vFor)
!(
memo &&
vFor &&
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid reprocessing v-for memo keys

When a v-memo element is also under v-for and its :key uses an outer-scope value such as :key="foo", transformFor has already processed the key to _ctx.foo. The structural v-for directive is spliced out before this element is traversed as the ForNode child, so this new vFor check is false here and the key is processed a second time, turning _ctx.foo into _ctx._ctx.foo in the generated render/cache comparison code. The skip still needs to cover keys already handled by transformFor while allowing only non-v-for v-memo keys through.

Useful? React with 👍 / 👎.

@edison1105
Copy link
Copy Markdown
Member

duplicate of #14922

@edison1105 edison1105 closed this Jun 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

compiler-core: :key expression not prefixed when element has v-memo without v-for (ReferenceError at runtime)

2 participants