Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 237ff5f

Browse filesBrowse files
authored
Merge branch 'main' into fix/prod-transition
2 parents f87f34f + 258f78b commit 237ff5f
Copy full SHA for 237ff5f

File tree

Expand file treeCollapse file tree

23 files changed

+1380
-820
lines changed
Filter options
Expand file treeCollapse file tree

23 files changed

+1380
-820
lines changed

‎CHANGELOG.md

Copy file name to clipboardExpand all lines: CHANGELOG.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* **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)
99
* **deps:** update dependency postcss to ^8.4.48 ([#12356](https://github.com/vuejs/core/issues/12356)) ([b5ff930](https://github.com/vuejs/core/commit/b5ff930089985a58c3553977ef999cec2a6708a4))
1010
* **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-
* **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)
11+
* **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)
1212
* **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)
1313
* **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)
1414
* **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

Copy file name to clipboardExpand all lines: package.json
+15-32Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"private": true,
33
"version": "3.5.13",
4-
"packageManager": "pnpm@10.8.0",
4+
"packageManager": "pnpm@10.9.0",
55
"type": "module",
66
"scripts": {
77
"dev": "node scripts/dev.js",
@@ -69,23 +69,23 @@
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.13",
72+
"@swc/core": "^1.11.24",
7373
"@types/hash-sum": "^1.0.2",
74-
"@types/node": "^22.14.0",
74+
"@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.2",
82+
"esbuild": "^0.25.4",
8383
"esbuild-plugin-polyfill-node": "^0.3.0",
84-
"eslint": "^9.23.0",
85-
"eslint-plugin-import-x": "^4.9.4",
84+
"eslint": "^9.25.1",
85+
"eslint-plugin-import-x": "^4.11.0",
8686
"estree-walker": "catalog:",
87-
"jsdom": "^26.0.0",
88-
"lint-staged": "^15.5.0",
87+
"jsdom": "^26.1.0",
88+
"lint-staged": "^15.5.1",
8989
"lodash": "^4.17.21",
9090
"magic-string": "^0.30.17",
9191
"markdown-table": "^3.0.4",
@@ -95,38 +95,21 @@
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.38.0",
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",
104104
"semver": "^7.7.1",
105105
"serve": "^14.2.4",
106106
"serve-handler": "^6.1.6",
107-
"simple-git-hooks": "^2.12.1",
107+
"simple-git-hooks": "^2.13.0",
108108
"todomvc-app-css": "^2.4.3",
109109
"tslib": "^2.8.1",
110110
"typescript": "~5.6.2",
111-
"typescript-eslint": "^8.28.0",
111+
"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

Copy file name to clipboardExpand all lines: packages-private/sfc-playground/src/download/template/package.json
+2-2Lines changed: 2 additions & 2 deletions
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.2.3"
14+
"@vitejs/plugin-vue": "^5.2.4",
15+
"vite": "^6.3.5"
1616
}
1717
}

‎packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts

Copy file name to clipboardExpand all lines: packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ describe('compiler: cacheStatic transform', () => {
170170
{
171171
/* _ slot flag */
172172
},
173+
{
174+
type: NodeTypes.JS_PROPERTY,
175+
key: { content: '__' },
176+
value: { content: '[0]' },
177+
},
173178
],
174179
})
175180
})
@@ -197,6 +202,11 @@ describe('compiler: cacheStatic transform', () => {
197202
{
198203
/* _ slot flag */
199204
},
205+
{
206+
type: NodeTypes.JS_PROPERTY,
207+
key: { content: '__' },
208+
value: { content: '[0]' },
209+
},
200210
],
201211
})
202212
})

‎packages/compiler-core/src/transforms/cacheStatic.ts

Copy file name to clipboardExpand all lines: packages/compiler-core/src/transforms/cacheStatic.ts
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ import {
1212
type RootNode,
1313
type SimpleExpressionNode,
1414
type SlotFunctionExpression,
15+
type SlotsObjectProperty,
1516
type TemplateChildNode,
1617
type TemplateNode,
1718
type TextCallNode,
1819
type VNodeCall,
1920
createArrayExpression,
21+
createObjectProperty,
22+
createSimpleExpression,
2023
getVNodeBlockHelper,
2124
getVNodeHelper,
2225
} from '../ast'
@@ -140,6 +143,7 @@ function walk(
140143
}
141144

142145
let cachedAsArray = false
146+
const slotCacheKeys = []
143147
if (toCache.length === children.length && node.type === NodeTypes.ELEMENT) {
144148
if (
145149
node.tagType === ElementTypes.ELEMENT &&
@@ -163,6 +167,7 @@ function walk(
163167
// default slot
164168
const slot = getSlotNode(node.codegenNode, 'default')
165169
if (slot) {
170+
slotCacheKeys.push(context.cached.length)
166171
slot.returns = getCacheExpression(
167172
createArrayExpression(slot.returns as TemplateChildNode[]),
168173
)
@@ -186,6 +191,7 @@ function walk(
186191
slotName.arg &&
187192
getSlotNode(parent.codegenNode, slotName.arg)
188193
if (slot) {
194+
slotCacheKeys.push(context.cached.length)
189195
slot.returns = getCacheExpression(
190196
createArrayExpression(slot.returns as TemplateChildNode[]),
191197
)
@@ -196,10 +202,31 @@ function walk(
196202

197203
if (!cachedAsArray) {
198204
for (const child of toCache) {
205+
slotCacheKeys.push(context.cached.length)
199206
child.codegenNode = context.cache(child.codegenNode!)
200207
}
201208
}
202209

210+
// put the slot cached keys on the slot object, so that the cache
211+
// can be removed when component unmounting to prevent memory leaks
212+
if (
213+
slotCacheKeys.length &&
214+
node.type === NodeTypes.ELEMENT &&
215+
node.tagType === ElementTypes.COMPONENT &&
216+
node.codegenNode &&
217+
node.codegenNode.type === NodeTypes.VNODE_CALL &&
218+
node.codegenNode.children &&
219+
!isArray(node.codegenNode.children) &&
220+
node.codegenNode.children.type === NodeTypes.JS_OBJECT_EXPRESSION
221+
) {
222+
node.codegenNode.children.properties.push(
223+
createObjectProperty(
224+
`__`,
225+
createSimpleExpression(JSON.stringify(slotCacheKeys), false),
226+
) as SlotsObjectProperty,
227+
)
228+
}
229+
203230
function getCacheExpression(value: JSChildNode): CacheExpression {
204231
const exp = context.cache(value)
205232
// #6978, #7138, #7114

‎packages/compiler-core/src/transforms/vSlot.ts

Copy file name to clipboardExpand all lines: packages/compiler-core/src/transforms/vSlot.ts
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,6 @@ export function buildSlots(
342342
: hasForwardedSlots(node.children)
343343
? SlotFlags.FORWARDED
344344
: SlotFlags.STABLE
345-
346345
let slots = createObjectExpression(
347346
slotsProperties.concat(
348347
createObjectProperty(

‎packages/compiler-sfc/__tests__/compileStyle.spec.ts

Copy file name to clipboardExpand all lines: packages/compiler-sfc/__tests__/compileStyle.spec.ts
+20-16Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -211,38 +211,42 @@ color: red
211211
expect(
212212
compileScoped(`.div { color: red; } .div:where(:hover) { color: blue; }`),
213213
).toMatchInlineSnapshot(`
214-
".div[data-v-test] { color: red;
215-
}
216-
.div[data-v-test]:where(:hover) { color: blue;
217-
}"`)
214+
".div[data-v-test] { color: red;
215+
}
216+
.div[data-v-test]:where(:hover) { color: blue;
217+
}"
218+
`)
218219

219220
expect(
220221
compileScoped(`.div { color: red; } .div:is(:hover) { color: blue; }`),
221222
).toMatchInlineSnapshot(`
222-
".div[data-v-test] { color: red;
223-
}
224-
.div[data-v-test]:is(:hover) { color: blue;
225-
}"`)
223+
".div[data-v-test] { color: red;
224+
}
225+
.div[data-v-test]:is(:hover) { color: blue;
226+
}"
227+
`)
226228

227229
expect(
228230
compileScoped(
229231
`.div { color: red; } .div:where(.foo:hover) { color: blue; }`,
230232
),
231233
).toMatchInlineSnapshot(`
232-
".div[data-v-test] { color: red;
233-
}
234-
.div[data-v-test]:where(.foo:hover) { color: blue;
235-
}"`)
234+
".div[data-v-test] { color: red;
235+
}
236+
.div[data-v-test]:where(.foo:hover) { color: blue;
237+
}"
238+
`)
236239

237240
expect(
238241
compileScoped(
239242
`.div { color: red; } .div:is(.foo:hover) { color: blue; }`,
240243
),
241244
).toMatchInlineSnapshot(`
242-
".div[data-v-test] { color: red;
243-
}
244-
.div[data-v-test]:is(.foo:hover) { color: blue;
245-
}"`)
245+
".div[data-v-test] { color: red;
246+
}
247+
.div[data-v-test]:is(.foo:hover) { color: blue;
248+
}"
249+
`)
246250
})
247251

248252
test('media query', () => {

‎packages/compiler-sfc/src/compileScript.ts

Copy file name to clipboardExpand all lines: packages/compiler-sfc/src/compileScript.ts
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,7 @@ function walkDeclaration(
11041104
m === userImportAliases['shallowRef'] ||
11051105
m === userImportAliases['customRef'] ||
11061106
m === userImportAliases['toRef'] ||
1107+
m === userImportAliases['useTemplateRef'] ||
11071108
m === DEFINE_MODEL,
11081109
)
11091110
) {

‎packages/reactivity/__tests__/computed.spec.ts

Copy file name to clipboardExpand all lines: packages/reactivity/__tests__/computed.spec.ts
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,17 @@ describe('reactivity/computed', () => {
10121012
expect(cValue.value).toBe(1)
10131013
})
10141014

1015+
test('should not recompute if computed does not track reactive data', async () => {
1016+
const spy = vi.fn()
1017+
const c1 = computed(() => spy())
1018+
1019+
c1.value
1020+
ref(0).value++ // update globalVersion
1021+
c1.value
1022+
1023+
expect(spy).toBeCalledTimes(1)
1024+
})
1025+
10151026
test('computed should remain live after losing all subscribers', () => {
10161027
const state = reactive({ a: 1 })
10171028
const p = computed(() => state.a + 1)

‎packages/reactivity/src/effect.ts

Copy file name to clipboardExpand all lines: packages/reactivity/src/effect.ts
+8-6Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export enum EffectFlags {
4949
DIRTY = 1 << 4,
5050
ALLOW_RECURSE = 1 << 5,
5151
PAUSED = 1 << 6,
52+
EVALUATED = 1 << 7,
5253
}
5354

5455
/**
@@ -377,22 +378,22 @@ export function refreshComputed(computed: ComputedRefImpl): undefined {
377378
}
378379
computed.globalVersion = globalVersion
379380

380-
const dep = computed.dep
381-
computed.flags |= EffectFlags.RUNNING
382381
// In SSR there will be no render effect, so the computed has no subscriber
383382
// and therefore tracks no deps, thus we cannot rely on the dirty check.
384383
// Instead, computed always re-evaluate and relies on the globalVersion
385384
// fast path above for caching.
385+
// #12337 if computed has no deps (does not rely on any reactive data) and evaluated,
386+
// there is no need to re-evaluate.
386387
if (
387-
dep.version > 0 &&
388388
!computed.isSSR &&
389-
computed.deps &&
390-
!isDirty(computed)
389+
computed.flags & EffectFlags.EVALUATED &&
390+
((!computed.deps && !(computed as any)._dirty) || !isDirty(computed))
391391
) {
392-
computed.flags &= ~EffectFlags.RUNNING
393392
return
394393
}
394+
computed.flags |= EffectFlags.RUNNING
395395

396+
const dep = computed.dep
396397
const prevSub = activeSub
397398
const prevShouldTrack = shouldTrack
398399
activeSub = computed
@@ -402,6 +403,7 @@ export function refreshComputed(computed: ComputedRefImpl): undefined {
402403
prepareDeps(computed)
403404
const value = computed.fn(computed._value)
404405
if (dep.version === 0 || hasChanged(value, computed._value)) {
406+
computed.flags |= EffectFlags.EVALUATED
405407
computed._value = value
406408
dep.version++
407409
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.