diff --git a/CHANGELOG.md b/CHANGELOG.md
index d45ad1087b4..2dbae4c79d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,41 @@
+## [3.5.14](https://github.com/vuejs/core/compare/v3.5.13...v3.5.14) (2025-05-15)
+
+
+### Bug Fixes
+
+* **compat:** correct deprecation message for v-bind.sync usage ([#13137](https://github.com/vuejs/core/issues/13137)) ([466b30f](https://github.com/vuejs/core/commit/466b30f4049ec89fb282624ec17d1a93472ab93f)), closes [#13133](https://github.com/vuejs/core/issues/13133)
+* **compiler-core:** remove slot cache from parent renderCache during unmounting ([#13215](https://github.com/vuejs/core/issues/13215)) ([5d166f3](https://github.com/vuejs/core/commit/5d166f3796a03a497435fc079c6a83a4e9c6cf52))
+* **compiler-sfc:** fix scope handling for props destructure in function parameters and catch clauses ([8e34357](https://github.com/vuejs/core/commit/8e3435779a667de485cf9efd78667d0ca14c5f84)), closes [#12790](https://github.com/vuejs/core/issues/12790)
+* **compiler-sfc:** treat the return value of `useTemplateRef` as a definite ref ([#13197](https://github.com/vuejs/core/issues/13197)) ([8ae1122](https://github.com/vuejs/core/commit/8ae11226e8ee938615e17c7b81dc38ae3f7cefb9))
+* **compiler:** fix spelling error in domTagConfig ([#13043](https://github.com/vuejs/core/issues/13043)) ([388295b](https://github.com/vuejs/core/commit/388295b27f3cc69eba25d325bbe60a36a3df831a))
+* **customFormatter:** properly accessing ref value during debugger ([#12948](https://github.com/vuejs/core/issues/12948)) ([fdbd026](https://github.com/vuejs/core/commit/fdbd02658301dd794fe0c84f0018d080a07fca9f))
+* **hmr/teleport:** adjust static children traversal for HMR in dev mode ([#12819](https://github.com/vuejs/core/issues/12819)) ([5e37dd0](https://github.com/vuejs/core/commit/5e37dd009562bcd8080a200c32abde2d6e4f0305)), closes [#12816](https://github.com/vuejs/core/issues/12816)
+* **hmr:** avoid hydration for hmr root reload ([#12450](https://github.com/vuejs/core/issues/12450)) ([1f98a9c](https://github.com/vuejs/core/commit/1f98a9c493d01c21befa90107f0593bc92a58932)), closes [vitejs/vite-plugin-vue#146](https://github.com/vitejs/vite-plugin-vue/issues/146) [vitejs/vite-plugin-vue#477](https://github.com/vitejs/vite-plugin-vue/issues/477)
+* **hmr:** avoid hydration for hmr updating ([#12262](https://github.com/vuejs/core/issues/12262)) ([9c4dbbc](https://github.com/vuejs/core/commit/9c4dbbc5185125835ad3e49baba303bd54676111)), closes [#7706](https://github.com/vuejs/core/issues/7706) [#8170](https://github.com/vuejs/core/issues/8170)
+* **reactivity:** ensure markRaw objects are not reactive ([#12824](https://github.com/vuejs/core/issues/12824)) ([295b5ec](https://github.com/vuejs/core/commit/295b5ec19b6a52c4a56652cc4d6e93a4ea7c14ed)), closes [#12807](https://github.com/vuejs/core/issues/12807)
+* **reactivity:** ensure multiple effectScope on() and off() calls maintains correct active scope ([22dcbf3](https://github.com/vuejs/core/commit/22dcbf3e20eb84f69c8952f6f70d9990136a4a68)), closes [#12631](https://github.com/vuejs/core/issues/12631) [#12632](https://github.com/vuejs/core/issues/12632) [#12641](https://github.com/vuejs/core/issues/12641)
+* **reactivity:** should not recompute if computed does not track reactive data ([#12341](https://github.com/vuejs/core/issues/12341)) ([0b23fd2](https://github.com/vuejs/core/commit/0b23fd23833cf085e7e112bf4435cfc9b360d072)), closes [#12337](https://github.com/vuejs/core/issues/12337)
+* **runtime-core:** stop tracking deps in setRef during unmount ([#13210](https://github.com/vuejs/core/issues/13210)) ([016c472](https://github.com/vuejs/core/commit/016c472bd2e7604b21c69dee1da8545ce26e4d2f))
+* **runtime-core:** update __vnode of static nodes when patching along the optimized path ([#13223](https://github.com/vuejs/core/issues/13223)) ([b3ecee3](https://github.com/vuejs/core/commit/b3ecee3da8ed5c55dea89ce6b4b376b2b722b018))
+* **runtime-core:** inherit comment nodes during block patch in production build ([#10748](https://github.com/vuejs/core/issues/10748)) ([6264505](https://github.com/vuejs/core/commit/626450590d81f79117b34d2a73073b1dc8f551bd)), closes [#10747](https://github.com/vuejs/core/issues/10747) [#12650](https://github.com/vuejs/core/issues/12650)
+* **runtime-core:** prevent unmounted vnode from being inserted during transition leave ([#12862](https://github.com/vuejs/core/issues/12862)) ([d6a6ec1](https://github.com/vuejs/core/commit/d6a6ec13ce521683bfb2a22932778ef7b51f8600)), closes [#12860](https://github.com/vuejs/core/issues/12860)
+* **runtime-core:** respect immutability for readonly reactive arrays in `v-for` ([#13091](https://github.com/vuejs/core/issues/13091)) ([3f27c58](https://github.com/vuejs/core/commit/3f27c58ffbd4309df369bc89493fdc284dc540bb)), closes [#13087](https://github.com/vuejs/core/issues/13087)
+* **runtime-dom:** always treat autocorrect as attribute ([#13001](https://github.com/vuejs/core/issues/13001)) ([1499135](https://github.com/vuejs/core/commit/1499135c227236e037bb746beeb777941b0b58ff)), closes [#5705](https://github.com/vuejs/core/issues/5705)
+* **slots:** properly warn if slot invoked in setup ([#12195](https://github.com/vuejs/core/issues/12195)) ([9196222](https://github.com/vuejs/core/commit/9196222ae1d63b52b35ac5fbf5e71494587ccf05)), closes [#12194](https://github.com/vuejs/core/issues/12194)
+* **ssr:** properly init slots during ssr rendering ([#12441](https://github.com/vuejs/core/issues/12441)) ([2206cd2](https://github.com/vuejs/core/commit/2206cd235a1627c540e795e378b7564a55b47313)), closes [#12438](https://github.com/vuejs/core/issues/12438)
+* **transition:** fix KeepAlive with transition out-in mode behavior in production ([#12468](https://github.com/vuejs/core/issues/12468)) ([343c891](https://github.com/vuejs/core/commit/343c89122448719bd6ed6bd9de986dfb2721d6bf)), closes [#12465](https://github.com/vuejs/core/issues/12465)
+* **TransitionGroup:** reset prevChildren to prevent memory leak ([#13183](https://github.com/vuejs/core/issues/13183)) ([8b848cb](https://github.com/vuejs/core/commit/8b848cbbd2af337d23e19e202f9ab433f8580855)), closes [#13181](https://github.com/vuejs/core/issues/13181)
+* **types:** allow return any for Options API lifecycle hooks ([#5914](https://github.com/vuejs/core/issues/5914)) ([06310e8](https://github.com/vuejs/core/commit/06310e82f5bed62d1b9733dcb18cd8d6edc988de))
+* **types:** the directive's modifiers should be optional ([#12605](https://github.com/vuejs/core/issues/12605)) ([10e54dc](https://github.com/vuejs/core/commit/10e54dcc86a7967f3196d96200bcbd1d3d42082f))
+* **typos:** fix comments referencing transformElement.ts ([#12551](https://github.com/vuejs/core/issues/12551))[ci-skip] ([11c053a](https://github.com/vuejs/core/commit/11c053a5429ad0d27a0e2c78b6b026ea00ace116))
+
+
+### Features
+
+* **types:** add type TemplateRef ([#12645](https://github.com/vuejs/core/issues/12645)) ([636a861](https://github.com/vuejs/core/commit/636a8619f06c71dfd79f7f6412fd130c4f84226f))
+
+
+
## [3.5.13](https://github.com/vuejs/core/compare/v3.5.12...v3.5.13) (2024-11-15)
@@ -8,7 +46,7 @@
* **custom-element:** avoid triggering mutationObserver when relecting props ([352bc88](https://github.com/vuejs/core/commit/352bc88c1bd2fda09c61ab17ea1a5967ffcd7bc0)), closes [#12214](https://github.com/vuejs/core/issues/12214) [#12215](https://github.com/vuejs/core/issues/12215)
* **deps:** update dependency postcss to ^8.4.48 ([#12356](https://github.com/vuejs/core/issues/12356)) ([b5ff930](https://github.com/vuejs/core/commit/b5ff930089985a58c3553977ef999cec2a6708a4))
* **hydration:** the component vnode's el should be updated when a mismatch occurs. ([#12255](https://github.com/vuejs/core/issues/12255)) ([a20a4cb](https://github.com/vuejs/core/commit/a20a4cb36a3e717d1f8f259d0d59f133f508ff0a)), closes [#12253](https://github.com/vuejs/core/issues/12253)
-* **reactiivty:** avoid unnecessary watcher effect removal from inactive scope ([2193284](https://github.com/vuejs/core/commit/21932840eae72ffcd357a62ec596aaecc7ec224a)), closes [#5783](https://github.com/vuejs/core/issues/5783) [#5806](https://github.com/vuejs/core/issues/5806)
+* **reactivity:** avoid unnecessary watcher effect removal from inactive scope ([2193284](https://github.com/vuejs/core/commit/21932840eae72ffcd357a62ec596aaecc7ec224a)), closes [#5783](https://github.com/vuejs/core/issues/5783) [#5806](https://github.com/vuejs/core/issues/5806)
* **reactivity:** release nested effects/scopes on effect scope stop ([#12373](https://github.com/vuejs/core/issues/12373)) ([bee2f5e](https://github.com/vuejs/core/commit/bee2f5ee62dc0cd04123b737779550726374dd0a)), closes [#12370](https://github.com/vuejs/core/issues/12370)
* **runtime-dom:** set css vars before user onMounted hooks ([2d5c5e2](https://github.com/vuejs/core/commit/2d5c5e25e9b7a56e883674fb434135ac514429b5)), closes [#11533](https://github.com/vuejs/core/issues/11533)
* **runtime-dom:** set css vars on update to handle child forcing reflow in onMount ([#11561](https://github.com/vuejs/core/issues/11561)) ([c4312f9](https://github.com/vuejs/core/commit/c4312f9c715c131a09e552ba46e9beb4b36d55e6))
diff --git a/README.md b/README.md
index 6dde821986a..6b4935abd4b 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,7 @@ Please make sure to respect issue requirements and use [the new issue helper](ht
## Stay In Touch
- [X](https://x.com/vuejs)
+- [Bluesky](https://bsky.app/profile/vuejs.org)
- [Blog](https://blog.vuejs.org/)
- [Job Board](https://vuejobs.com/?ref=vuejs)
diff --git a/package.json b/package.json
index e541df36d94..3542fe215de 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"private": true,
- "version": "3.5.13",
- "packageManager": "pnpm@10.7.0",
+ "version": "3.5.14",
+ "packageManager": "pnpm@10.9.0",
"type": "module",
"scripts": {
"dev": "node scripts/dev.js",
@@ -69,23 +69,23 @@
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-replace": "5.0.4",
- "@swc/core": "^1.11.13",
+ "@swc/core": "^1.11.24",
"@types/hash-sum": "^1.0.2",
- "@types/node": "^22.13.14",
+ "@types/node": "^22.14.1",
"@types/semver": "^7.7.0",
"@types/serve-handler": "^6.1.4",
- "@vitest/coverage-v8": "^3.0.9",
- "@vitest/eslint-plugin": "^1.1.38",
+ "@vitest/coverage-v8": "^3.1.3",
+ "@vitest/eslint-plugin": "^1.1.44",
"@vue/consolidate": "1.0.0",
"conventional-changelog-cli": "^5.0.0",
"enquirer": "^2.4.1",
- "esbuild": "^0.25.2",
+ "esbuild": "^0.25.4",
"esbuild-plugin-polyfill-node": "^0.3.0",
- "eslint": "^9.23.0",
- "eslint-plugin-import-x": "^4.9.4",
+ "eslint": "^9.25.1",
+ "eslint-plugin-import-x": "^4.11.0",
"estree-walker": "catalog:",
- "jsdom": "^26.0.0",
- "lint-staged": "^15.5.0",
+ "jsdom": "^26.1.0",
+ "lint-staged": "^15.5.1",
"lodash": "^4.17.21",
"magic-string": "^0.30.17",
"markdown-table": "^3.0.4",
@@ -95,38 +95,21 @@
"prettier": "^3.5.3",
"pretty-bytes": "^6.1.1",
"pug": "^3.0.3",
- "puppeteer": "~24.4.0",
+ "puppeteer": "~24.8.2",
"rimraf": "^6.0.1",
- "rollup": "^4.38.0",
+ "rollup": "^4.40.2",
"rollup-plugin-dts": "^6.2.1",
"rollup-plugin-esbuild": "^6.2.1",
"rollup-plugin-polyfill-node": "^0.13.0",
"semver": "^7.7.1",
"serve": "^14.2.4",
"serve-handler": "^6.1.6",
- "simple-git-hooks": "^2.12.1",
+ "simple-git-hooks": "^2.13.0",
"todomvc-app-css": "^2.4.3",
"tslib": "^2.8.1",
"typescript": "~5.6.2",
- "typescript-eslint": "^8.28.0",
+ "typescript-eslint": "^8.31.1",
"vite": "catalog:",
- "vitest": "^3.0.9"
- },
- "pnpm": {
- "peerDependencyRules": {
- "allowedVersions": {
- "typescript-eslint>eslint": "^9.0.0",
- "@typescript-eslint/eslint-plugin>eslint": "^9.0.0",
- "@typescript-eslint/parser>eslint": "^9.0.0",
- "@typescript-eslint/type-utils>eslint": "^9.0.0",
- "@typescript-eslint/utils>eslint": "^9.0.0"
- }
- },
- "onlyBuiltDependencies": [
- "@swc/core",
- "esbuild",
- "puppeteer",
- "simple-git-hooks"
- ]
+ "vitest": "^3.1.3"
}
}
diff --git a/packages-private/sfc-playground/src/download/template/package.json b/packages-private/sfc-playground/src/download/template/package.json
index 4ed7e58f26c..b9bb278edf3 100644
--- a/packages-private/sfc-playground/src/download/template/package.json
+++ b/packages-private/sfc-playground/src/download/template/package.json
@@ -11,7 +11,7 @@
"vue": "latest"
},
"devDependencies": {
- "@vitejs/plugin-vue": "^5.2.3",
- "vite": "^6.2.3"
+ "@vitejs/plugin-vue": "^5.2.4",
+ "vite": "^6.3.5"
}
}
diff --git a/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts b/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts
index ab5ed7baede..358c0e31c3d 100644
--- a/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts
@@ -170,6 +170,11 @@ describe('compiler: cacheStatic transform', () => {
{
/* _ slot flag */
},
+ {
+ type: NodeTypes.JS_PROPERTY,
+ key: { content: '__' },
+ value: { content: '[0]' },
+ },
],
})
})
@@ -197,6 +202,11 @@ describe('compiler: cacheStatic transform', () => {
{
/* _ slot flag */
},
+ {
+ type: NodeTypes.JS_PROPERTY,
+ key: { content: '__' },
+ value: { content: '[0]' },
+ },
],
})
})
diff --git a/packages/compiler-core/package.json b/packages/compiler-core/package.json
index d2f474c5983..7311f46935f 100644
--- a/packages/compiler-core/package.json
+++ b/packages/compiler-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-core",
- "version": "3.5.13",
+ "version": "3.5.14",
"description": "@vue/compiler-core",
"main": "index.js",
"module": "dist/compiler-core.esm-bundler.js",
diff --git a/packages/compiler-core/src/transforms/cacheStatic.ts b/packages/compiler-core/src/transforms/cacheStatic.ts
index 8d5961643c1..e5d67380640 100644
--- a/packages/compiler-core/src/transforms/cacheStatic.ts
+++ b/packages/compiler-core/src/transforms/cacheStatic.ts
@@ -12,11 +12,14 @@ import {
type RootNode,
type SimpleExpressionNode,
type SlotFunctionExpression,
+ type SlotsObjectProperty,
type TemplateChildNode,
type TemplateNode,
type TextCallNode,
type VNodeCall,
createArrayExpression,
+ createObjectProperty,
+ createSimpleExpression,
getVNodeBlockHelper,
getVNodeHelper,
} from '../ast'
@@ -140,6 +143,7 @@ function walk(
}
let cachedAsArray = false
+ const slotCacheKeys = []
if (toCache.length === children.length && node.type === NodeTypes.ELEMENT) {
if (
node.tagType === ElementTypes.ELEMENT &&
@@ -163,6 +167,7 @@ function walk(
// default slot
const slot = getSlotNode(node.codegenNode, 'default')
if (slot) {
+ slotCacheKeys.push(context.cached.length)
slot.returns = getCacheExpression(
createArrayExpression(slot.returns as TemplateChildNode[]),
)
@@ -186,6 +191,7 @@ function walk(
slotName.arg &&
getSlotNode(parent.codegenNode, slotName.arg)
if (slot) {
+ slotCacheKeys.push(context.cached.length)
slot.returns = getCacheExpression(
createArrayExpression(slot.returns as TemplateChildNode[]),
)
@@ -196,10 +202,31 @@ function walk(
if (!cachedAsArray) {
for (const child of toCache) {
+ slotCacheKeys.push(context.cached.length)
child.codegenNode = context.cache(child.codegenNode!)
}
}
+ // put the slot cached keys on the slot object, so that the cache
+ // can be removed when component unmounting to prevent memory leaks
+ if (
+ slotCacheKeys.length &&
+ node.type === NodeTypes.ELEMENT &&
+ node.tagType === ElementTypes.COMPONENT &&
+ node.codegenNode &&
+ node.codegenNode.type === NodeTypes.VNODE_CALL &&
+ node.codegenNode.children &&
+ !isArray(node.codegenNode.children) &&
+ node.codegenNode.children.type === NodeTypes.JS_OBJECT_EXPRESSION
+ ) {
+ node.codegenNode.children.properties.push(
+ createObjectProperty(
+ `__`,
+ createSimpleExpression(JSON.stringify(slotCacheKeys), false),
+ ) as SlotsObjectProperty,
+ )
+ }
+
function getCacheExpression(value: JSChildNode): CacheExpression {
const exp = context.cache(value)
// #6978, #7138, #7114
diff --git a/packages/compiler-core/src/transforms/vSlot.ts b/packages/compiler-core/src/transforms/vSlot.ts
index db367f39c0c..28625439a47 100644
--- a/packages/compiler-core/src/transforms/vSlot.ts
+++ b/packages/compiler-core/src/transforms/vSlot.ts
@@ -342,7 +342,6 @@ export function buildSlots(
: hasForwardedSlots(node.children)
? SlotFlags.FORWARDED
: SlotFlags.STABLE
-
let slots = createObjectExpression(
slotsProperties.concat(
createObjectProperty(
diff --git a/packages/compiler-dom/package.json b/packages/compiler-dom/package.json
index 1be062a2722..18745d38654 100644
--- a/packages/compiler-dom/package.json
+++ b/packages/compiler-dom/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-dom",
- "version": "3.5.13",
+ "version": "3.5.14",
"description": "@vue/compiler-dom",
"main": "index.js",
"module": "dist/compiler-dom.esm-bundler.js",
diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap
index 1044b0e167c..9306d31da97 100644
--- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap
@@ -192,6 +192,25 @@ return () => {}
}"
`;
+exports[`sfc reactive props destructure > handle function parameters with same name as destructured props 1`] = `
+"
+export default {
+ setup(__props) {
+
+
+ function test(value) {
+ try {
+ } catch {
+ }
+ }
+ console.log(__props.value)
+
+return () => {}
+}
+
+}"
+`;
+
exports[`sfc reactive props destructure > multi-variable declaration 1`] = `
"
export default {
diff --git a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
index 50602eb59bc..25dd817bbe5 100644
--- a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
@@ -358,6 +358,22 @@ describe('sfc reactive props destructure', () => {
expect(content).toMatch(`props: ['item'],`)
})
+ test('handle function parameters with same name as destructured props', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+ expect(content).toMatch(`console.log(__props.value)`)
+ })
+
test('defineProps/defineEmits in multi-variable declaration (full removal)', () => {
const { content } = compile(`