Skip to content

Commit 6c8e63d

Browse files
committed
Merge branch 'main' into alien-signals
2 parents 66dd59c + 6eb29d3 commit 6c8e63d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+775
-85
lines changed

CHANGELOG.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,36 @@
1+
## [3.5.13](https://github.com/vuejs/core/compare/v3.5.12...v3.5.13) (2024-11-15)
2+
3+
4+
### Bug Fixes
5+
6+
* **compiler-core:** handle v-memo + v-for with functional key ([#12014](https://github.com/vuejs/core/issues/12014)) ([99009ee](https://github.com/vuejs/core/commit/99009eee0efc238392daba93792d478525b21afa)), closes [#12013](https://github.com/vuejs/core/issues/12013)
7+
* **compiler-dom:** properly stringify template string style ([#12392](https://github.com/vuejs/core/issues/12392)) ([2d78539](https://github.com/vuejs/core/commit/2d78539da35322aea5f821b3cf9b02d006abac72)), closes [#12391](https://github.com/vuejs/core/issues/12391)
8+
* **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)
9+
* **deps:** update dependency postcss to ^8.4.48 ([#12356](https://github.com/vuejs/core/issues/12356)) ([b5ff930](https://github.com/vuejs/core/commit/b5ff930089985a58c3553977ef999cec2a6708a4))
10+
* **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)
12+
* **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)
13+
* **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)
14+
* **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))
15+
* **ssr:** avoid updating subtree of async component if it is resolved ([#12363](https://github.com/vuejs/core/issues/12363)) ([da7ad5e](https://github.com/vuejs/core/commit/da7ad5e3d24f3e108401188d909d27a4910da095)), closes [#12362](https://github.com/vuejs/core/issues/12362)
16+
* **ssr:** ensure v-text updates correctly with custom directives in SSR output ([#12311](https://github.com/vuejs/core/issues/12311)) ([1f75d4e](https://github.com/vuejs/core/commit/1f75d4e6dfe18121ebe443cd3e8105d54f727893)), closes [#12309](https://github.com/vuejs/core/issues/12309)
17+
* **ssr:** handle initial selected state for select with v-model + v-for option ([#12399](https://github.com/vuejs/core/issues/12399)) ([4f8d807](https://github.com/vuejs/core/commit/4f8d8078221ee52deed266677a227ad2a6d8dd22)), closes [#12395](https://github.com/vuejs/core/issues/12395)
18+
* **teleport:** handle deferred teleport update before mounted ([#12168](https://github.com/vuejs/core/issues/12168)) ([8bff142](https://github.com/vuejs/core/commit/8bff142f99b646e9dd15897ec75368fbf34f1534)), closes [#12161](https://github.com/vuejs/core/issues/12161)
19+
* **templateRef:** set ref on cached async component which wrapped in KeepAlive ([#12290](https://github.com/vuejs/core/issues/12290)) ([983eb50](https://github.com/vuejs/core/commit/983eb50a17eac76f1bba4394ad0316c62b72191d)), closes [#4999](https://github.com/vuejs/core/issues/4999) [#5004](https://github.com/vuejs/core/issues/5004)
20+
* **test:** update snapshot ([#12169](https://github.com/vuejs/core/issues/12169)) ([828d4a4](https://github.com/vuejs/core/commit/828d4a443919fa2aa4e2e92fbd03a5f04b258eea))
21+
* **Transition:** fix transition memory leak edge case ([#12182](https://github.com/vuejs/core/issues/12182)) ([660132d](https://github.com/vuejs/core/commit/660132df6c6a8c14bf75e593dc47d2fdada30322)), closes [#12181](https://github.com/vuejs/core/issues/12181)
22+
* **transition:** reflow before leave-active class after leave-from ([#12288](https://github.com/vuejs/core/issues/12288)) ([4b479db](https://github.com/vuejs/core/commit/4b479db61d233b054561402ae94ef08550073ea1)), closes [#2593](https://github.com/vuejs/core/issues/2593)
23+
* **types:** defineEmits w/ interface declaration ([#12343](https://github.com/vuejs/core/issues/12343)) ([1022eab](https://github.com/vuejs/core/commit/1022eabaa1aaf8436876f5ec5573cb1e4b3959a6)), closes [#8457](https://github.com/vuejs/core/issues/8457)
24+
* **v-once:** setting hasOnce to current block only when in v-once ([#12374](https://github.com/vuejs/core/issues/12374)) ([37300fc](https://github.com/vuejs/core/commit/37300fc26190a7299efddbf98800ffd96d5cad96)), closes [#12371](https://github.com/vuejs/core/issues/12371)
25+
26+
27+
### Performance Improvements
28+
29+
* **reactivity:** do not track inner key `__v_skip`` ([#11690](https://github.com/vuejs/core/issues/11690)) ([d637bd6](https://github.com/vuejs/core/commit/d637bd6c0164c2883e6eabd3c2f1f8c258dedfb1))
30+
* **runtime-core:** use feature flag for call to resolveMergedOptions ([#12163](https://github.com/vuejs/core/issues/12163)) ([1755ac0](https://github.com/vuejs/core/commit/1755ac0a108ba3486bd8397e56d3bdcd69196594))
31+
32+
33+
134
## [3.5.12](https://github.com/vuejs/core/compare/v3.5.11...v3.5.12) (2024-10-11)
235

336

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"private": true,
3-
"version": "3.5.12",
3+
"version": "3.5.13",
44
"packageManager": "[email protected]",
55
"type": "module",
66
"scripts": {

packages-private/dts-test/setupHelpers.test-d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,14 @@ describe('defineEmits w/ type declaration', () => {
306306
emit2('baz')
307307
})
308308

309+
describe('defineEmits w/ interface declaration', () => {
310+
interface Emits {
311+
foo: [value: string]
312+
}
313+
const emit = defineEmits<Emits>()
314+
emit('foo', 'hi')
315+
})
316+
309317
describe('defineEmits w/ alt type declaration', () => {
310318
const emit = defineEmits<{
311319
foo: [id: string]

packages-private/sfc-playground/src/Header.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ function resetVueVersion() {
4646
4747
async function copyLink(e: MouseEvent) {
4848
if (e.metaKey) {
49+
resetVueVersion()
4950
// hidden logic for going to local debug from play.vuejs.org
5051
window.location.href = 'http://localhost:5173/' + window.location.hash
5152
return

packages/compiler-core/package.json

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

packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ return function render(_ctx, _cache) {
3232
}"
3333
`;
3434

35+
exports[`stringify static html > serializing template string style 1`] = `
36+
"const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
37+
38+
return function render(_ctx, _cache) {
39+
return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
40+
_createStaticVNode("<div style=\\"color:red;\\"><span class=\\"foo bar\\">1 + false</span><span class=\\"foo bar\\">1 + false</span><span class=\\"foo bar\\">1 + false</span><span class=\\"foo bar\\">1 + false</span><span class=\\"foo bar\\">1 + false</span></div>", 1)
41+
])))
42+
}"
43+
`;
44+
3545
exports[`stringify static html > should bail for <option> elements with null values 1`] = `
3646
"const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
3747

packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,27 @@ describe('stringify static html', () => {
162162
expect(code).toMatchSnapshot()
163163
})
164164

165+
// #12391
166+
test('serializing template string style', () => {
167+
const { ast, code } = compileWithStringify(
168+
`<div><div :style="\`color:red;\`">${repeat(
169+
`<span :class="[{ foo: true }, { bar: true }]">{{ 1 }} + {{ false }}</span>`,
170+
StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
171+
)}</div></div>`,
172+
)
173+
// should be optimized now
174+
expect(ast.cached).toMatchObject([
175+
cachedArrayStaticNodeMatcher(
176+
`<div style="color:red;">${repeat(
177+
`<span class="foo bar">1 + false</span>`,
178+
StringifyThresholds.ELEMENT_WITH_BINDING_COUNT,
179+
)}</div>`,
180+
1,
181+
),
182+
])
183+
expect(code).toMatchSnapshot()
184+
})
185+
165186
test('escape', () => {
166187
const { ast, code } = compileWithStringify(
167188
`<div><div>${repeat(

packages/compiler-dom/package.json

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

packages/compiler-sfc/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vue/compiler-sfc",
3-
"version": "3.5.12",
3+
"version": "3.5.13",
44
"description": "@vue/compiler-sfc",
55
"main": "dist/compiler-sfc.cjs.js",
66
"module": "dist/compiler-sfc.esm-browser.js",
@@ -60,7 +60,7 @@
6060
"merge-source-map": "^1.1.0",
6161
"minimatch": "~9.0.5",
6262
"postcss-modules": "^6.0.0",
63-
"postcss-selector-parser": "^6.1.2",
63+
"postcss-selector-parser": "^7.0.0",
6464
"pug": "^3.0.3",
6565
"sass": "^1.80.6"
6666
}

packages/compiler-sfc/src/style/pluginScoped.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,7 @@ function rewriteSelector(
189189
// global: replace with inner selector and do not inject [id].
190190
// ::v-global(.foo) -> .foo
191191
if (value === ':global' || value === '::v-global') {
192-
selectorRoot.insertAfter(selector, n.nodes[0])
193-
selectorRoot.removeChild(selector)
192+
selector.replaceWith(n.nodes[0])
194193
return false
195194
}
196195
}

packages/compiler-ssr/__tests__/ssrElement.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,39 @@ describe('ssr: element', () => {
337337
`)
338338
})
339339

340+
test('custom dir with v-text', () => {
341+
expect(getCompiledString(`<div v-xxx v-text="foo" />`))
342+
.toMatchInlineSnapshot(`
343+
"\`<div\${
344+
_ssrRenderAttrs(_ssrGetDirectiveProps(_ctx, _directive_xxx))
345+
}>\${
346+
_ssrInterpolate(_ctx.foo)
347+
}</div>\`"
348+
`)
349+
})
350+
351+
test('custom dir with v-text and normal attrs', () => {
352+
expect(getCompiledString(`<div class="test" v-xxx v-text="foo" />`))
353+
.toMatchInlineSnapshot(`
354+
"\`<div\${
355+
_ssrRenderAttrs(_mergeProps({ class: "test" }, _ssrGetDirectiveProps(_ctx, _directive_xxx)))
356+
}>\${
357+
_ssrInterpolate(_ctx.foo)
358+
}</div>\`"
359+
`)
360+
})
361+
362+
test('mulptiple custom dirs with v-text', () => {
363+
expect(getCompiledString(`<div v-xxx v-yyy v-text="foo" />`))
364+
.toMatchInlineSnapshot(`
365+
"\`<div\${
366+
_ssrRenderAttrs(_mergeProps(_ssrGetDirectiveProps(_ctx, _directive_xxx), _ssrGetDirectiveProps(_ctx, _directive_yyy)))
367+
}>\${
368+
_ssrInterpolate(_ctx.foo)
369+
}</div>\`"
370+
`)
371+
})
372+
340373
test('custom dir with object v-bind', () => {
341374
expect(getCompiledString(`<div v-bind="x" v-xxx />`))
342375
.toMatchInlineSnapshot(`

packages/compiler-ssr/__tests__/ssrVModel.spec.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,52 @@ describe('ssr: v-model', () => {
5252
}"
5353
`)
5454

55+
expect(
56+
compileWithWrapper(
57+
`<select v-model="model"><option v-for="i in items" :value="i"></option></select>`,
58+
).code,
59+
).toMatchInlineSnapshot(`
60+
"const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs, ssrRenderList: _ssrRenderList } = require("vue/server-renderer")
61+
62+
return function ssrRender(_ctx, _push, _parent, _attrs) {
63+
_push(\`<div\${_ssrRenderAttrs(_attrs)}><select><!--[-->\`)
64+
_ssrRenderList(_ctx.items, (i) => {
65+
_push(\`<option\${
66+
_ssrRenderAttr("value", i)
67+
}\${
68+
(_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
69+
? _ssrLooseContain(_ctx.model, i)
70+
: _ssrLooseEqual(_ctx.model, i))) ? " selected" : ""
71+
}></option>\`)
72+
})
73+
_push(\`<!--]--></select></div>\`)
74+
}"
75+
`)
76+
77+
expect(
78+
compileWithWrapper(
79+
`<select v-model="model"><option v-if="true" :value="i"></option></select>`,
80+
).code,
81+
).toMatchInlineSnapshot(`
82+
"const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
83+
84+
return function ssrRender(_ctx, _push, _parent, _attrs) {
85+
_push(\`<div\${_ssrRenderAttrs(_attrs)}><select>\`)
86+
if (true) {
87+
_push(\`<option\${
88+
_ssrRenderAttr("value", _ctx.i)
89+
}\${
90+
(_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
91+
? _ssrLooseContain(_ctx.model, _ctx.i)
92+
: _ssrLooseEqual(_ctx.model, _ctx.i))) ? " selected" : ""
93+
}></option>\`)
94+
} else {
95+
_push(\`<!---->\`)
96+
}
97+
_push(\`</select></div>\`)
98+
}"
99+
`)
100+
55101
expect(
56102
compileWithWrapper(
57103
`<select multiple v-model="model"><option value="1" selected></option><option value="2"></option></select>`,

packages/compiler-ssr/package.json

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

packages/compiler-ssr/src/transforms/ssrTransformElement.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
createSequenceExpression,
2929
createSimpleExpression,
3030
createTemplateLiteral,
31+
findDir,
3132
hasDynamicKeyVBind,
3233
isStaticArgOf,
3334
isStaticExp,
@@ -164,24 +165,28 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
164165
]
165166
}
166167
} else if (directives.length && !node.children.length) {
167-
const tempId = `_temp${context.temps++}`
168-
propsExp.arguments = [
169-
createAssignmentExpression(
170-
createSimpleExpression(tempId, false),
171-
mergedProps,
172-
),
173-
]
174-
rawChildrenMap.set(
175-
node,
176-
createConditionalExpression(
177-
createSimpleExpression(`"textContent" in ${tempId}`, false),
178-
createCallExpression(context.helper(SSR_INTERPOLATE), [
179-
createSimpleExpression(`${tempId}.textContent`, false),
180-
]),
181-
createSimpleExpression(`${tempId}.innerHTML ?? ''`, false),
182-
false,
183-
),
184-
)
168+
// v-text directive has higher priority than the merged props
169+
const vText = findDir(node, 'text')
170+
if (!vText) {
171+
const tempId = `_temp${context.temps++}`
172+
propsExp.arguments = [
173+
createAssignmentExpression(
174+
createSimpleExpression(tempId, false),
175+
mergedProps,
176+
),
177+
]
178+
rawChildrenMap.set(
179+
node,
180+
createConditionalExpression(
181+
createSimpleExpression(`"textContent" in ${tempId}`, false),
182+
createCallExpression(context.helper(SSR_INTERPOLATE), [
183+
createSimpleExpression(`${tempId}.textContent`, false),
184+
]),
185+
createSimpleExpression(`${tempId}.innerHTML ?? ''`, false),
186+
false,
187+
),
188+
)
189+
}
185190
}
186191

187192
if (needTagForRuntime) {

packages/compiler-ssr/src/transforms/ssrVModel.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
type ExpressionNode,
66
NodeTypes,
77
type PlainElementNode,
8+
type TemplateChildNode,
89
createCallExpression,
910
createConditionalExpression,
1011
createDOMCompilerError,
@@ -162,11 +163,18 @@ export const ssrTransformModel: DirectiveTransform = (dir, node, context) => {
162163
checkDuplicatedValue()
163164
node.children = [createInterpolation(model, model.loc)]
164165
} else if (node.tag === 'select') {
165-
node.children.forEach(child => {
166-
if (child.type === NodeTypes.ELEMENT) {
167-
processOption(child as PlainElementNode)
168-
}
169-
})
166+
const processChildren = (children: TemplateChildNode[]) => {
167+
children.forEach(child => {
168+
if (child.type === NodeTypes.ELEMENT) {
169+
processOption(child as PlainElementNode)
170+
} else if (child.type === NodeTypes.FOR) {
171+
processChildren(child.children)
172+
} else if (child.type === NodeTypes.IF) {
173+
child.branches.forEach(b => processChildren(b.children))
174+
}
175+
})
176+
}
177+
processChildren(node.children)
170178
} else {
171179
context.onError(
172180
createDOMCompilerError(

packages/reactivity/package.json

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

packages/reactivity/src/baseHandlers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class BaseReactiveHandler implements ProxyHandler<Target> {
5353
) {}
5454

5555
get(target: Target, key: string | symbol, receiver: object): any {
56+
if (key === ReactiveFlags.SKIP) return target[ReactiveFlags.SKIP]
57+
5658
const isReadonly = this._isReadonly,
5759
isShallow = this._isShallow
5860
if (key === ReactiveFlags.IS_REACTIVE) {

packages/reactivity/src/effectScope.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,8 @@ export class EffectScope implements Subscriber {
133133
this.depsTail = undefined
134134
}
135135
let i, l
136-
const effects = this.effects.slice()
137-
for (i = 0, l = effects.length; i < l; i++) {
138-
effects[i].stop()
136+
for (i = 0, l = this.effects.length; i < l; i++) {
137+
this.effects[i].stop()
139138
}
140139
this.effects.length = 0
141140

0 commit comments

Comments
 (0)