diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 9816f7f5257..95bc65f357b 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -31,4 +31,4 @@ jobs: - name: Run prettier run: pnpm run format - - uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef + - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b84bd85cb7..2a0b96332b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,54 @@ +## [3.5.18](https://github.com/vuejs/core/compare/v3.5.17...v3.5.18) (2025-07-23) + + +### Bug Fixes + +* **compiler-core:** avoid cached text vnodes retaining detached DOM nodes ([#13662](https://github.com/vuejs/core/issues/13662)) ([00695a5](https://github.com/vuejs/core/commit/00695a5b41b2d032deaeada83831ff83aa6bfd4e)), closes [#13661](https://github.com/vuejs/core/issues/13661) +* **compiler-core:** avoid self updates of `v-pre` ([#12556](https://github.com/vuejs/core/issues/12556)) ([21b685a](https://github.com/vuejs/core/commit/21b685ad9d9d0e6060fc7d07b719bf35f2d9ae1f)) +* **compiler-core:** identifiers in function parameters should not be inferred as references ([#13548](https://github.com/vuejs/core/issues/13548)) ([9b02923](https://github.com/vuejs/core/commit/9b029239edf88558465b941e1e4c085f92b1ebff)) +* **compiler-core:** recognize empty string as non-identifier ([#12553](https://github.com/vuejs/core/issues/12553)) ([ce93339](https://github.com/vuejs/core/commit/ce933390ad1c72bed258f7ad959a78f0e8acdf57)) +* **compiler-core:** transform empty `v-bind` dynamic argument content correctly ([#12554](https://github.com/vuejs/core/issues/12554)) ([d3af67e](https://github.com/vuejs/core/commit/d3af67e878790892f9d34cfea15d13625aabe733)) +* **compiler-sfc:** transform empty srcset w/ includeAbsolute: true ([#13639](https://github.com/vuejs/core/issues/13639)) ([d8e40ef](https://github.com/vuejs/core/commit/d8e40ef7e1c20ee86b294e7cf78e2de60d12830e)), closes [vitejs/vite-plugin-vue#631](https://github.com/vitejs/vite-plugin-vue/issues/631) +* **css-vars:** nullish v-bind in style should not lead to unexpected inheritance ([#12461](https://github.com/vuejs/core/issues/12461)) ([c85f1b5](https://github.com/vuejs/core/commit/c85f1b5a132eb8ec25f71b250e25e65a5c20964f)), closes [#12434](https://github.com/vuejs/core/issues/12434) [#12439](https://github.com/vuejs/core/issues/12439) [#7474](https://github.com/vuejs/core/issues/7474) [#7475](https://github.com/vuejs/core/issues/7475) +* **custom-element:** ensure exposed methods are accessible from custom elements by making them enumerable ([#13634](https://github.com/vuejs/core/issues/13634)) ([90573b0](https://github.com/vuejs/core/commit/90573b06bf6fb6c14c6bbff6c4e34e0ab108953a)), closes [#13632](https://github.com/vuejs/core/issues/13632) +* **hydration:** prevent lazy hydration for updated components ([#13511](https://github.com/vuejs/core/issues/13511)) ([a9269c6](https://github.com/vuejs/core/commit/a9269c642bf944560bc29adb5dae471c11cd9ee8)), closes [#13510](https://github.com/vuejs/core/issues/13510) +* **runtime-core:** ensure correct anchor el for unresolved async components ([#13560](https://github.com/vuejs/core/issues/13560)) ([7f29943](https://github.com/vuejs/core/commit/7f2994393dcdb82cacbf62e02b5ba5565f32588b)), closes [#13559](https://github.com/vuejs/core/issues/13559) +* **slots:** refine internal key checking to support slot names starting with an underscore ([#13612](https://github.com/vuejs/core/issues/13612)) ([c5f7db1](https://github.com/vuejs/core/commit/c5f7db11542bb2246363aef78c88a8e6cef0ee93)), closes [#13611](https://github.com/vuejs/core/issues/13611) +* **ssr:** ensure empty slots render as a comment node in Transition ([#13396](https://github.com/vuejs/core/issues/13396)) ([8cfc10a](https://github.com/vuejs/core/commit/8cfc10a80b9cbf5d801ab149e49b8506d192e7e1)), closes [#13394](https://github.com/vuejs/core/issues/13394) + + + +## [3.5.17](https://github.com/vuejs/core/compare/v3.5.16...v3.5.17) (2025-06-18) + + +### Bug Fixes + +* **compat:** allow v-model built in modifiers on component ([#12654](https://github.com/vuejs/core/issues/12654)) ([cb14b86](https://github.com/vuejs/core/commit/cb14b860f150c4a83bcd52cd26096b7a5aa3a2bf)), closes [#12652](https://github.com/vuejs/core/issues/12652) +* **compile-sfc:** handle mapped types work with omit and pick ([#12648](https://github.com/vuejs/core/issues/12648)) ([4eb46e4](https://github.com/vuejs/core/commit/4eb46e443f1878199755cb73d481d318a9714392)), closes [#12647](https://github.com/vuejs/core/issues/12647) +* **compiler-core:** do not increase newlines in `InEntity` state ([#13362](https://github.com/vuejs/core/issues/13362)) ([f05a8d6](https://github.com/vuejs/core/commit/f05a8d613bd873b811cfdb9979ccac8382dba322)) +* **compiler-core:** ignore whitespace when matching adjacent v-if ([#12321](https://github.com/vuejs/core/issues/12321)) ([10ebcef](https://github.com/vuejs/core/commit/10ebcef8c870dbc042b0ea49b1424b2e8f692145)), closes [#9173](https://github.com/vuejs/core/issues/9173) +* **compiler-core:** prevent comments from blocking static node hoisting ([#13345](https://github.com/vuejs/core/issues/13345)) ([55dad62](https://github.com/vuejs/core/commit/55dad625acd9e9ddd5a933d5e323ecfdec1a612f)), closes [#13344](https://github.com/vuejs/core/issues/13344) +* **compiler-sfc:** improved type resolution for function type aliases ([#13452](https://github.com/vuejs/core/issues/13452)) ([f3479aa](https://github.com/vuejs/core/commit/f3479aac9625f4459e650d1c0a70e73863147903)), closes [#13444](https://github.com/vuejs/core/issues/13444) +* **custom-element:** ensure configureApp is applied to async component ([#12607](https://github.com/vuejs/core/issues/12607)) ([5ba1afb](https://github.com/vuejs/core/commit/5ba1afba09c3ea56c1c17484f5d8aeae210ce52a)), closes [#12448](https://github.com/vuejs/core/issues/12448) +* **custom-element:** prevent injecting child styles if shadowRoot is false ([#12769](https://github.com/vuejs/core/issues/12769)) ([73055d8](https://github.com/vuejs/core/commit/73055d8d9578d485e3fe846726b50666e1aa56f5)), closes [#12630](https://github.com/vuejs/core/issues/12630) +* **reactivity:** add `__v_skip` flag to `Dep` to prevent reactive conversion ([#12804](https://github.com/vuejs/core/issues/12804)) ([e8d8f5f](https://github.com/vuejs/core/commit/e8d8f5f604e821acc46b4200d5b06979c05af1c2)), closes [#12803](https://github.com/vuejs/core/issues/12803) +* **runtime-core:** unset old ref during patching when new ref is absent ([#12900](https://github.com/vuejs/core/issues/12900)) ([47ddf98](https://github.com/vuejs/core/commit/47ddf986021dff8de68b0da72787e53a6c19de4c)), closes [#12898](https://github.com/vuejs/core/issues/12898) +* **slots:** make cache indexes marker non-enumerable ([#13469](https://github.com/vuejs/core/issues/13469)) ([919c447](https://github.com/vuejs/core/commit/919c44744bba1f0c661c87d2059c3b429611aa7e)), closes [#13468](https://github.com/vuejs/core/issues/13468) +* **ssr:** handle initial selected state for select with v-model + v-for/v-if option ([#13487](https://github.com/vuejs/core/issues/13487)) ([1552095](https://github.com/vuejs/core/commit/15520954f9f1c7f834175938a50dba5d4be0e6c4)), closes [#13486](https://github.com/vuejs/core/issues/13486) +* **types:** typo of `vOnce` and `vSlot` ([#13343](https://github.com/vuejs/core/issues/13343)) ([762fae4](https://github.com/vuejs/core/commit/762fae4b57ad60602e5c84465a3bff562785b314)) + + + +## [3.5.16](https://github.com/vuejs/core/compare/v3.5.15...v3.5.16) (2025-05-29) + + +### Reverts + +* Revert "fix(compiler-sfc): add scoping tag to trailing universal selector" (#13406) ([19f23b1](https://github.com/vuejs/core/commit/19f23b180bb679e38db95d6a10a420abeedc8e1c)), closes [#13406](https://github.com/vuejs/core/issues/13406) +* Revert "fix(compiler-sfc): add error handling for defineModel() without variable" (#13390) ([42f879f](https://github.com/vuejs/core/commit/42f879fcab48e0e1011967a771b4ad9e8838d760)), closes [#13390](https://github.com/vuejs/core/issues/13390) + + + ## [3.5.15](https://github.com/vuejs/core/compare/v3.5.14...v3.5.15) (2025-05-26) diff --git a/changelogs/CHANGELOG-3.0.md b/changelogs/CHANGELOG-3.0.md index 16483767fe4..c19ef26890b 100644 --- a/changelogs/CHANGELOG-3.0.md +++ b/changelogs/CHANGELOG-3.0.md @@ -56,13 +56,13 @@ - **hydration:** handle camel-case tag name when performing match assertion ([#3247](https://github.com/vuejs/core/issues/3247)) ([9036f88](https://github.com/vuejs/core/commit/9036f88d8304a3455265f1ecd86ec8f4a5ea4715)), closes [#3243](https://github.com/vuejs/core/issues/3243) - **KeepAlive:** adapt keepalive for ssr ([#3259](https://github.com/vuejs/core/issues/3259)) ([e8e9b00](https://github.com/vuejs/core/commit/e8e9b00f81ed42434afd92f84101e7a14d70a23c)), closes [#3255](https://github.com/vuejs/core/issues/3255) - **reactivity:** ensure computed can be wrapped by readonly ([41e02f0](https://github.com/vuejs/core/commit/41e02f0fac069c93c94438741517e713f3c94215)), closes [#3376](https://github.com/vuejs/core/issues/3376) -- **reactivity:** ensure that shallow and normal proxies are tracked seperately (close [#2843](https://github.com/vuejs/core/issues/2843)) ([#2851](https://github.com/vuejs/core/issues/2851)) ([22cc4a7](https://github.com/vuejs/core/commit/22cc4a76592cfe336e75e2fa0c05232ae1f0f149)) +- **reactivity:** ensure that shallow and normal proxies are tracked separately (close [#2843](https://github.com/vuejs/core/issues/2843)) ([#2851](https://github.com/vuejs/core/issues/2851)) ([22cc4a7](https://github.com/vuejs/core/commit/22cc4a76592cfe336e75e2fa0c05232ae1f0f149)) - **reactivity:** fix shallow readonly behavior for collections ([#3003](https://github.com/vuejs/core/issues/3003)) ([68de9f4](https://github.com/vuejs/core/commit/68de9f408a2e61a5726a4a0d03b026cba451c5bd)), closes [#3007](https://github.com/vuejs/core/issues/3007) - **rumtime-core:** custom dom props should be cloned when cloning a hoisted DOM ([#3080](https://github.com/vuejs/core/issues/3080)) ([5dbe834](https://github.com/vuejs/core/commit/5dbe8348581dacd7a3594a9b0055ce350ce8e5bf)), closes [#3072](https://github.com/vuejs/core/issues/3072) - **runtime-core:** cache props default values to avoid unnecessary watcher trigger ([#3474](https://github.com/vuejs/core/issues/3474)) ([44166b4](https://github.com/vuejs/core/commit/44166b43d9be1062f79612880f71284049bcab0b)), closes [#3471](https://github.com/vuejs/core/issues/3471) - **runtime-core:** ensure only skip unflushed job ([#3406](https://github.com/vuejs/core/issues/3406)) ([bf34e33](https://github.com/vuejs/core/commit/bf34e33c909da89681b9c5004cdf04ab198ec5a7)) - **runtime-core:** fix async component ref handling ([#3191](https://github.com/vuejs/core/issues/3191)) ([7562e72](https://github.com/vuejs/core/commit/7562e72c2b58a5646bd4fbd9adea11eb884fe140)), closes [#3188](https://github.com/vuejs/core/issues/3188) -- **runtime-core:** fix erraneous emits warnings w/ mixins ([60d777d](https://github.com/vuejs/core/commit/60d777d228414515cc32526ad72a53ef070501be)), closes [#2651](https://github.com/vuejs/core/issues/2651) +- **runtime-core:** fix erroneous emits warnings w/ mixins ([60d777d](https://github.com/vuejs/core/commit/60d777d228414515cc32526ad72a53ef070501be)), closes [#2651](https://github.com/vuejs/core/issues/2651) - **runtime-core:** fix warning for absent props ([#3363](https://github.com/vuejs/core/issues/3363)) ([86ceef4](https://github.com/vuejs/core/commit/86ceef43523bfbbb0a24731d3802ca6849cbefd6)), closes [#3362](https://github.com/vuejs/core/issues/3362) - **runtime-core:** handle error in async setup ([#2881](https://github.com/vuejs/core/issues/2881)) ([d668d48](https://github.com/vuejs/core/commit/d668d48e9e5211a49ee53361ea5b4d67ba16e0a3)) - **runtime-core:** handle error in async watchEffect ([#3129](https://github.com/vuejs/core/issues/3129)) ([eb1fae6](https://github.com/vuejs/core/commit/eb1fae63f926435fb0eef890663d24e09d4c79e1)) @@ -202,7 +202,7 @@ may cause build issues in projects still using TS 3.x. - **script-setup:** ensure useContext() return valid context ([73cdb9d](https://github.com/vuejs/core/commit/73cdb9d4208f887fe08349657122e39175d7166c)) - **slots:** dynamically named slots should be keyed by name ([2ab8c41](https://github.com/vuejs/core/commit/2ab8c41a1a43952fb229587a9da48d9a1214ab9e)), closes [#2535](https://github.com/vuejs/core/issues/2535) - **slots:** should render fallback content when slot content contains no valid nodes ([#2485](https://github.com/vuejs/core/issues/2485)) ([ce4915d](https://github.com/vuejs/core/commit/ce4915d8bed12f4cdb5fa8ca39bda98d0d3aabb7)), closes [#2347](https://github.com/vuejs/core/issues/2347) [#2461](https://github.com/vuejs/core/issues/2461) -- **suspense:** fix nested async child toggle inside already resovled suspense ([cf7f1db](https://github.com/vuejs/core/commit/cf7f1dbc9be8d50ad220e3630c38f5a9a217d693)), closes [#2215](https://github.com/vuejs/core/issues/2215) +- **suspense:** fix nested async child toggle inside already resolved suspense ([cf7f1db](https://github.com/vuejs/core/commit/cf7f1dbc9be8d50ad220e3630c38f5a9a217d693)), closes [#2215](https://github.com/vuejs/core/issues/2215) - **teleport:** Teleport into SVG elements ([#2648](https://github.com/vuejs/core/issues/2648)) ([cd92836](https://github.com/vuejs/core/commit/cd928362232747a51d1fd4790bb20adcdd59d187)), closes [#2652](https://github.com/vuejs/core/issues/2652) - **transition:** avoid invoking stale transition end callbacks ([eaf8a67](https://github.com/vuejs/core/commit/eaf8a67c7219e1b79d6abca44a1d7f1b341b58b0)), closes [#2482](https://github.com/vuejs/core/issues/2482) - **transition:** respect rules in \*-leave-from transition class ([#2597](https://github.com/vuejs/core/issues/2597)) ([e2618a6](https://github.com/vuejs/core/commit/e2618a632d4add2819ffb8b575af0da189dc3204)), closes [#2593](https://github.com/vuejs/core/issues/2593) @@ -236,7 +236,7 @@ may cause build issues in projects still using TS 3.x. - **compiler-sfc:** compileScript inline render function mode ([886ed76](https://github.com/vuejs/core/commit/886ed7681dd203c07ff3b504538328f43e14d9b0)) - **compiler-sfc:** new script setup implementation ([556560f](https://github.com/vuejs/core/commit/556560fae31d9e406cfae656089657b6332686c1)) -- **compiler-sfc:** new SFC css varaible injection implementation ([41bb7fa](https://github.com/vuejs/core/commit/41bb7fa330e78c4a354a2e67742bd13bee2f4293)) +- **compiler-sfc:** new SFC css variable injection implementation ([41bb7fa](https://github.com/vuejs/core/commit/41bb7fa330e78c4a354a2e67742bd13bee2f4293)) - **compiler-sfc:** support kebab-case components in ` @@ -141,20 +169,11 @@ onMounted(() => { :editorOptions="{ autoSaveText: false }" :store="store" :showCompileOutput="true" + :showSsrOutput="useSSRMode" + :showOpenSourceMap="true" :autoResize="true" :clearConsole="false" - :preview-options="{ - customCode: { - importCode: `import { initCustomFormatter } from 'vue'`, - useCode: `if (window.devtoolsFormatters) { - const index = window.devtoolsFormatters.findIndex((v) => v.__vue_custom_formatter) - window.devtoolsFormatters.splice(index, 1) - initCustomFormatter() - } else { - initCustomFormatter() - }`, - }, - }" + :preview-options="previewOptions" /> diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts index 4e5a9616511..cdc2b09fd48 100644 --- a/packages/compiler-core/__tests__/parse.spec.ts +++ b/packages/compiler-core/__tests__/parse.spec.ts @@ -2271,6 +2271,11 @@ describe('compiler: parse', () => { expect(span.loc.start.offset).toBe(0) expect(span.loc.end.offset).toBe(27) }) + + test('correct loc when a line in attribute value ends with &', () => { + const [span] = baseParse(``).children + expect(span.loc.end.line).toBe(2) + }) }) describe('decodeEntities option', () => { diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap index 375a0c8674a..91a82db5bba 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap @@ -8,7 +8,7 @@ return function render(_ctx, _cache) { const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [ - _createElementVNode("div", { key: "foo" }, null, -1 /* HOISTED */) + _createElementVNode("div", { key: "foo" }, null, -1 /* CACHED */) ]))) } }" @@ -25,11 +25,11 @@ return function render(_ctx, _cache) { _createElementVNode("p", null, [ _createElementVNode("span"), _createElementVNode("span") - ], -1 /* HOISTED */), + ], -1 /* CACHED */), _createElementVNode("p", null, [ _createElementVNode("span"), _createElementVNode("span") - ], -1 /* HOISTED */) + ], -1 /* CACHED */) ]))) } }" @@ -45,7 +45,7 @@ return function render(_ctx, _cache) { return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [ _createElementVNode("div", null, [ _createCommentVNode("comment") - ], -1 /* HOISTED */) + ], -1 /* CACHED */) ]))) } }" @@ -59,9 +59,9 @@ return function render(_ctx, _cache) { const { createElementVNode: _createElementVNode, createTextVNode: _createTextVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [ - _createElementVNode("span", null, null, -1 /* HOISTED */), - _createTextVNode("foo"), - _createElementVNode("div", null, null, -1 /* HOISTED */) + _createElementVNode("span", null, null, -1 /* CACHED */), + _createTextVNode("foo", -1 /* CACHED */), + _createElementVNode("div", null, null, -1 /* CACHED */) ]))) } }" @@ -75,7 +75,7 @@ return function render(_ctx, _cache) { const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [ - _createElementVNode("span", { class: "inline" }, "hello", -1 /* HOISTED */) + _createElementVNode("span", { class: "inline" }, "hello", -1 /* CACHED */) ]))) } }" @@ -148,7 +148,7 @@ return function render(_ctx, _cache) { const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [ - _createElementVNode("span", null, "foo " + _toDisplayString(1) + " " + _toDisplayString(true), -1 /* HOISTED */) + _createElementVNode("span", null, "foo " + _toDisplayString(1) + " " + _toDisplayString(true), -1 /* CACHED */) ]))) } }" @@ -162,7 +162,7 @@ return function render(_ctx, _cache) { const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [ - _createElementVNode("span", { foo: 0 }, _toDisplayString(1), -1 /* HOISTED */) + _createElementVNode("span", { foo: 0 }, _toDisplayString(1), -1 /* CACHED */) ]))) } }" @@ -178,7 +178,7 @@ return function render(_ctx, _cache) { return (_openBlock(), _createElementBlock("div", null, [ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(1, (i) => { return (_openBlock(), _createElementBlock("div", null, [...(_cache[0] || (_cache[0] = [ - _createElementVNode("span", { class: "hi" }, null, -1 /* HOISTED */) + _createElementVNode("span", { class: "hi" }, null, -1 /* CACHED */) ]))])) }), 256 /* UNKEYED_FRAGMENT */)) ])) @@ -216,7 +216,7 @@ return function render(_ctx, _cache) { return (_openBlock(), _createElementBlock("div", null, [ _withDirectives((_openBlock(), _createElementBlock("svg", null, _cache[0] || (_cache[0] = [ - _createElementVNode("path", { d: "M2,3H5.5L12" }, null, -1 /* HOISTED */) + _createElementVNode("path", { d: "M2,3H5.5L12" }, null, -1 /* CACHED */) ]))), [ [_directive_foo] ]) @@ -402,7 +402,7 @@ return function render(_ctx, _cache) { return (_openBlock(), _createElementBlock("div", null, [ ok ? (_openBlock(), _createElementBlock("div", _hoisted_1, _cache[0] || (_cache[0] = [ - _createElementVNode("span", null, null, -1 /* HOISTED */) + _createElementVNode("span", null, null, -1 /* CACHED */) ]))) : _createCommentVNode("v-if", true) ])) @@ -410,6 +410,32 @@ return function render(_ctx, _cache) { }" `; +exports[`compiler: cacheStatic transform > should hoist props for root with single element excluding comments 1`] = ` +"const _Vue = Vue +const { createElementVNode: _createElementVNode, createCommentVNode: _createCommentVNode } = _Vue + +const _hoisted_1 = { id: "a" } + +return function render(_ctx, _cache) { + with (_ctx) { + const { createCommentVNode: _createCommentVNode, createElementVNode: _createElementVNode, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue + + return (_openBlock(), _createElementBlock(_Fragment, null, [ + _createCommentVNode("comment"), + _createElementVNode("div", _hoisted_1, _cache[0] || (_cache[0] = [ + _createElementVNode("div", { id: "b" }, [ + _createElementVNode("div", { id: "c" }, [ + _createElementVNode("div", { id: "d" }, [ + _createElementVNode("div", { id: "e" }, "hello") + ]) + ]) + ], -1 /* CACHED */) + ])) + ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */)) + } +}" +`; + exports[`compiler: cacheStatic transform > should hoist v-for children if static 1`] = ` "const _Vue = Vue const { createElementVNode: _createElementVNode } = _Vue @@ -423,7 +449,7 @@ return function render(_ctx, _cache) { return (_openBlock(), _createElementBlock("div", null, [ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(list, (i) => { return (_openBlock(), _createElementBlock("div", _hoisted_1, _cache[0] || (_cache[0] = [ - _createElementVNode("span", null, null, -1 /* HOISTED */) + _createElementVNode("span", null, null, -1 /* CACHED */) ]))) }), 256 /* UNKEYED_FRAGMENT */)) ])) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap index 0d9c0e743de..2cd13bab036 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap @@ -246,6 +246,28 @@ return function render(_ctx, _cache) { }" `; +exports[`compiler: transform component slots > with whitespace: 'preserve' > named slot with v-if + v-else 1`] = ` +"const { resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = Vue + +return function render(_ctx, _cache) { + const _component_Comp = _resolveComponent("Comp") + + return (_openBlock(), _createBlock(_component_Comp, null, _createSlots({ _: 2 /* DYNAMIC */ }, [ + ok + ? { + name: "one", + fn: _withCtx(() => ["foo"]), + key: "0" + } + : { + name: "two", + fn: _withCtx(() => ["baz"]), + key: "1" + } + ]), 1024 /* DYNAMIC_SLOTS */)) +}" +`; + exports[`compiler: transform component slots > with whitespace: 'preserve' > should not generate whitespace only default slot 1`] = ` "const { resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue diff --git a/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts b/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts index 358c0e31c3d..74f6caca328 100644 --- a/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts +++ b/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts @@ -543,6 +543,32 @@ describe('compiler: cacheStatic transform', () => { expect(generate(root).code).toMatchSnapshot() }) + test('should hoist props for root with single element excluding comments', () => { + // deeply nested div to trigger stringification condition + const root = transformWithCache( + `