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(`