Skip to content

Commit 66cc8d1

Browse files
authored
Merge branch 'main' into edison/fix/13261
2 parents bb76e0f + b991075 commit 66cc8d1

File tree

28 files changed

+826
-531
lines changed

28 files changed

+826
-531
lines changed

CHANGELOG.md

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,41 @@
1+
## [3.5.14](https://github.com/vuejs/core/compare/v3.5.13...v3.5.14) (2025-05-15)
2+
3+
4+
### Bug Fixes
5+
6+
* **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)
7+
* **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))
8+
* **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)
9+
* **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))
10+
* **compiler:** fix spelling error in domTagConfig ([#13043](https://github.com/vuejs/core/issues/13043)) ([388295b](https://github.com/vuejs/core/commit/388295b27f3cc69eba25d325bbe60a36a3df831a))
11+
* **customFormatter:** properly accessing ref value during debugger ([#12948](https://github.com/vuejs/core/issues/12948)) ([fdbd026](https://github.com/vuejs/core/commit/fdbd02658301dd794fe0c84f0018d080a07fca9f))
12+
* **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)
13+
* **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)
14+
* **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)
15+
* **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)
16+
* **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)
17+
* **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)
18+
* **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))
19+
* **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))
20+
* **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)
21+
* **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)
22+
* **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)
23+
* **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)
24+
* **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)
25+
* **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)
26+
* **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)
27+
* **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)
28+
* **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))
29+
* **types:** the directive's modifiers should be optional ([#12605](https://github.com/vuejs/core/issues/12605)) ([10e54dc](https://github.com/vuejs/core/commit/10e54dcc86a7967f3196d96200bcbd1d3d42082f))
30+
* **typos:** fix comments referencing transformElement.ts ([#12551](https://github.com/vuejs/core/issues/12551))[ci-skip] ([11c053a](https://github.com/vuejs/core/commit/11c053a5429ad0d27a0e2c78b6b026ea00ace116))
31+
32+
33+
### Features
34+
35+
* **types:** add type TemplateRef ([#12645](https://github.com/vuejs/core/issues/12645)) ([636a861](https://github.com/vuejs/core/commit/636a8619f06c71dfd79f7f6412fd130c4f84226f))
36+
37+
38+
139
## [3.5.13](https://github.com/vuejs/core/compare/v3.5.12...v3.5.13) (2024-11-15)
240

341

@@ -8,7 +46,7 @@
846
* **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)
947
* **deps:** update dependency postcss to ^8.4.48 ([#12356](https://github.com/vuejs/core/issues/12356)) ([b5ff930](https://github.com/vuejs/core/commit/b5ff930089985a58c3553977ef999cec2a6708a4))
1048
* **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)
11-
* **reactivty:** 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)
49+
* **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)
1250
* **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)
1351
* **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)
1452
* **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))

package.json

+9-26
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"private": true,
3-
"version": "3.5.13",
3+
"version": "3.5.14",
44
"packageManager": "[email protected]",
55
"type": "module",
66
"scripts": {
@@ -69,22 +69,22 @@
6969
"@rollup/plugin-json": "^6.1.0",
7070
"@rollup/plugin-node-resolve": "^16.0.1",
7171
"@rollup/plugin-replace": "5.0.4",
72-
"@swc/core": "^1.11.21",
72+
"@swc/core": "^1.11.24",
7373
"@types/hash-sum": "^1.0.2",
7474
"@types/node": "^22.14.1",
7575
"@types/semver": "^7.7.0",
7676
"@types/serve-handler": "^6.1.4",
77-
"@vitest/coverage-v8": "^3.0.9",
78-
"@vitest/eslint-plugin": "^1.1.38",
77+
"@vitest/coverage-v8": "^3.1.3",
78+
"@vitest/eslint-plugin": "^1.1.44",
7979
"@vue/consolidate": "1.0.0",
8080
"conventional-changelog-cli": "^5.0.0",
8181
"enquirer": "^2.4.1",
82-
"esbuild": "^0.25.3",
82+
"esbuild": "^0.25.4",
8383
"esbuild-plugin-polyfill-node": "^0.3.0",
8484
"eslint": "^9.25.1",
8585
"eslint-plugin-import-x": "^4.11.0",
8686
"estree-walker": "catalog:",
87-
"jsdom": "^26.0.0",
87+
"jsdom": "^26.1.0",
8888
"lint-staged": "^15.5.1",
8989
"lodash": "^4.17.21",
9090
"magic-string": "^0.30.17",
@@ -95,9 +95,9 @@
9595
"prettier": "^3.5.3",
9696
"pretty-bytes": "^6.1.1",
9797
"pug": "^3.0.3",
98-
"puppeteer": "~24.4.0",
98+
"puppeteer": "~24.8.2",
9999
"rimraf": "^6.0.1",
100-
"rollup": "^4.40.1",
100+
"rollup": "^4.40.2",
101101
"rollup-plugin-dts": "^6.2.1",
102102
"rollup-plugin-esbuild": "^6.2.1",
103103
"rollup-plugin-polyfill-node": "^0.13.0",
@@ -110,23 +110,6 @@
110110
"typescript": "~5.6.2",
111111
"typescript-eslint": "^8.31.1",
112112
"vite": "catalog:",
113-
"vitest": "^3.0.9"
114-
},
115-
"pnpm": {
116-
"peerDependencyRules": {
117-
"allowedVersions": {
118-
"typescript-eslint>eslint": "^9.0.0",
119-
"@typescript-eslint/eslint-plugin>eslint": "^9.0.0",
120-
"@typescript-eslint/parser>eslint": "^9.0.0",
121-
"@typescript-eslint/type-utils>eslint": "^9.0.0",
122-
"@typescript-eslint/utils>eslint": "^9.0.0"
123-
}
124-
},
125-
"onlyBuiltDependencies": [
126-
"@swc/core",
127-
"esbuild",
128-
"puppeteer",
129-
"simple-git-hooks"
130-
]
113+
"vitest": "^3.1.3"
131114
}
132115
}

packages-private/sfc-playground/src/download/template/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"vue": "latest"
1212
},
1313
"devDependencies": {
14-
"@vitejs/plugin-vue": "^5.2.3",
15-
"vite": "^6.3.3"
14+
"@vitejs/plugin-vue": "^5.2.4",
15+
"vite": "^6.3.5"
1616
}
1717
}

packages/compiler-core/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vue/compiler-core",
3-
"version": "3.5.13",
3+
"version": "3.5.14",
44
"description": "@vue/compiler-core",
55
"main": "index.js",
66
"module": "dist/compiler-core.esm-bundler.js",

packages/compiler-dom/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vue/compiler-dom",
3-
"version": "3.5.13",
3+
"version": "3.5.14",
44
"description": "@vue/compiler-dom",
55
"main": "index.js",
66
"module": "dist/compiler-dom.esm-bundler.js",

packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap

+19
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,25 @@ return () => {}
192192
}"
193193
`;
194194

195+
exports[`sfc reactive props destructure > handle function parameters with same name as destructured props 1`] = `
196+
"
197+
export default {
198+
setup(__props) {
199+
200+
201+
function test(value) {
202+
try {
203+
} catch {
204+
}
205+
}
206+
console.log(__props.value)
207+
208+
return () => {}
209+
}
210+
211+
}"
212+
`;
213+
195214
exports[`sfc reactive props destructure > multi-variable declaration 1`] = `
196215
"
197216
export default {

packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts

+16
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,22 @@ describe('sfc reactive props destructure', () => {
358358
expect(content).toMatch(`props: ['item'],`)
359359
})
360360

361+
test('handle function parameters with same name as destructured props', () => {
362+
const { content } = compile(`
363+
<script setup>
364+
const { value } = defineProps()
365+
function test(value) {
366+
try {
367+
} catch {
368+
}
369+
}
370+
console.log(value)
371+
</script>
372+
`)
373+
assertCode(content)
374+
expect(content).toMatch(`console.log(__props.value)`)
375+
})
376+
361377
test('defineProps/defineEmits in multi-variable declaration (full removal)', () => {
362378
const { content } = compile(`
363379
<script setup>

packages/compiler-sfc/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vue/compiler-sfc",
3-
"version": "3.5.13",
3+
"version": "3.5.14",
44
"description": "@vue/compiler-sfc",
55
"main": "dist/compiler-sfc.cjs.js",
66
"module": "dist/compiler-sfc.esm-browser.js",

packages/compiler-sfc/src/script/definePropsDestructure.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ export function transformDestructuredProps(
291291
parent && parentStack.pop()
292292
if (
293293
(node.type === 'BlockStatement' && !isFunctionType(parent!)) ||
294-
isFunctionType(node)
294+
isFunctionType(node) ||
295+
node.type === 'CatchClause'
295296
) {
296297
popScope()
297298
}

packages/compiler-ssr/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vue/compiler-ssr",
3-
"version": "3.5.13",
3+
"version": "3.5.14",
44
"description": "@vue/compiler-ssr",
55
"main": "dist/compiler-ssr.cjs.js",
66
"types": "dist/compiler-ssr.d.ts",

packages/reactivity/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vue/reactivity",
3-
"version": "3.5.13",
3+
"version": "3.5.14",
44
"description": "@vue/reactivity",
55
"main": "index.js",
66
"module": "dist/reactivity.esm-bundler.js",

packages/runtime-core/__tests__/components/BaseTransition.spec.ts

+47
Original file line numberDiff line numberDiff line change
@@ -1198,4 +1198,51 @@ describe('BaseTransition', () => {
11981198
test('should not error on KeepAlive w/ function children', () => {
11991199
expect(() => mount({}, () => () => h('div'), true)).not.toThrow()
12001200
})
1201+
1202+
// #12465
1203+
test('mode: "out-in" w/ KeepAlive + fallthrough attrs (prod mode)', async () => {
1204+
__DEV__ = false
1205+
async function testOutIn({ trueBranch, falseBranch }: ToggleOptions) {
1206+
const toggle = ref(true)
1207+
const { props, cbs } = mockProps({ mode: 'out-in' }, true)
1208+
const root = nodeOps.createElement('div')
1209+
const App = {
1210+
render() {
1211+
return h(
1212+
BaseTransition,
1213+
{
1214+
...props,
1215+
class: 'test',
1216+
},
1217+
() =>
1218+
h(KeepAlive, null, toggle.value ? trueBranch() : falseBranch()),
1219+
)
1220+
},
1221+
}
1222+
render(h(App), root)
1223+
1224+
expect(serializeInner(root)).toBe(`<div class="test">0</div>`)
1225+
1226+
// trigger toggle
1227+
toggle.value = false
1228+
await nextTick()
1229+
expect(props.onBeforeLeave).toHaveBeenCalledTimes(1)
1230+
expect(serialize((props.onBeforeLeave as any).mock.calls[0][0])).toBe(
1231+
`<div class="test">0</div>`,
1232+
)
1233+
expect(props.onLeave).toHaveBeenCalledTimes(1)
1234+
expect(serialize((props.onLeave as any).mock.calls[0][0])).toBe(
1235+
`<div class="test">0</div>`,
1236+
)
1237+
expect(props.onAfterLeave).not.toHaveBeenCalled()
1238+
// enter should not have started
1239+
expect(props.onBeforeEnter).not.toHaveBeenCalled()
1240+
expect(props.onEnter).not.toHaveBeenCalled()
1241+
expect(props.onAfterEnter).not.toHaveBeenCalled()
1242+
cbs.doneLeave[`<div class="test">0</div>`]()
1243+
expect(serializeInner(root)).toBe(`<span class="test">0</span>`)
1244+
}
1245+
await runTestWithKeepAlive(testOutIn)
1246+
__DEV__ = true
1247+
})
12011248
})

packages/runtime-core/__tests__/components/Teleport.spec.ts

+71-1
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,19 @@ import {
1414
h as originalH,
1515
ref,
1616
render,
17+
serialize,
1718
serializeInner,
1819
withDirectives,
1920
} from '@vue/runtime-test'
20-
import { Fragment, createCommentVNode, createVNode } from '../../src/vnode'
21+
import {
22+
Fragment,
23+
createBlock,
24+
createCommentVNode,
25+
createTextVNode,
26+
createVNode,
27+
openBlock,
28+
} from '../../src/vnode'
29+
import { toDisplayString } from '@vue/shared'
2130
import { compile, createApp as createDOMApp, render as domRender } from 'vue'
2231
import type { HMRRuntime } from '../../src/hmr'
2332

@@ -248,6 +257,39 @@ describe('renderer: teleport', () => {
248257
expect(serializeInner(target)).toBe(`teleported`)
249258
})
250259

260+
test('should traverse comment node after updating in optimize mode', async () => {
261+
const target = nodeOps.createElement('div')
262+
const root = nodeOps.createElement('div')
263+
const count = ref(0)
264+
let teleport
265+
266+
__DEV__ = false
267+
render(
268+
h(() => {
269+
teleport =
270+
(openBlock(),
271+
createBlock(Teleport, { to: target }, [
272+
createCommentVNode('comment in teleport'),
273+
]))
274+
return h('div', null, [
275+
createTextVNode(toDisplayString(count.value)),
276+
teleport,
277+
])
278+
}),
279+
root,
280+
)
281+
const commentNode = teleport!.children[0].el
282+
expect(serializeInner(root)).toBe(`<div>0</div>`)
283+
expect(serializeInner(target)).toBe(`<!--comment in teleport-->`)
284+
expect(serialize(commentNode)).toBe(`<!--comment in teleport-->`)
285+
286+
count.value = 1
287+
await nextTick()
288+
__DEV__ = true
289+
expect(serializeInner(root)).toBe(`<div>1</div>`)
290+
expect(teleport!.children[0].el).toBe(commentNode)
291+
})
292+
251293
test('should remove children when unmounted', () => {
252294
const target = nodeOps.createElement('div')
253295
const root = nodeOps.createElement('div')
@@ -274,6 +316,34 @@ describe('renderer: teleport', () => {
274316
testUnmount({ to: null, disabled: true })
275317
})
276318

319+
// #10747
320+
test('should unmount correctly when using top level comment in teleport', async () => {
321+
const target = nodeOps.createElement('div')
322+
const root = nodeOps.createElement('div')
323+
const count = ref(0)
324+
325+
__DEV__ = false
326+
render(
327+
h(() => {
328+
return h('div', null, [
329+
createTextVNode(toDisplayString(count.value)),
330+
(openBlock(),
331+
createBlock(Teleport, { to: target }, [
332+
createCommentVNode('comment in teleport'),
333+
])),
334+
])
335+
}),
336+
root,
337+
)
338+
339+
count.value = 1
340+
341+
await nextTick()
342+
__DEV__ = true
343+
render(null, root)
344+
expect(root.children.length).toBe(0)
345+
})
346+
277347
test('component with multi roots should be removed when unmounted', () => {
278348
const target = nodeOps.createElement('div')
279349
const root = nodeOps.createElement('div')

0 commit comments

Comments
 (0)