diff --git a/.github/contributing.md b/.github/contributing.md
index 2554582b8..681d26e69 100644
--- a/.github/contributing.md
+++ b/.github/contributing.md
@@ -290,27 +290,39 @@ This is made possible via several configurations:
```mermaid
flowchart LR
+ vue["vue"]
compiler-sfc["@vue/compiler-sfc"]
compiler-dom["@vue/compiler-dom"]
+ compiler-vapor["@vue/compiler-vapor"]
compiler-core["@vue/compiler-core"]
- vue["vue"]
runtime-dom["@vue/runtime-dom"]
+ runtime-vapor["@vue/runtime-vapor"]
runtime-core["@vue/runtime-core"]
reactivity["@vue/reactivity"]
subgraph "Runtime Packages"
runtime-dom --> runtime-core
+ runtime-vapor --> runtime-core
runtime-core --> reactivity
end
subgraph "Compiler Packages"
compiler-sfc --> compiler-core
compiler-sfc --> compiler-dom
+ compiler-sfc --> compiler-vapor
compiler-dom --> compiler-core
+ compiler-vapor --> compiler-core
end
+ vue --> compiler-sfc
vue ---> compiler-dom
vue --> runtime-dom
+ vue --> compiler-vapor
+ vue --> runtime-vapor
+
+ %% Highlight class
+ classDef highlight stroke:#35eb9a,stroke-width:3px;
+ class compiler-vapor,runtime-vapor highlight;
```
There are some rules to follow when importing across package boundaries:
diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml
index 3ef9bbce5..9816f7f52 100644
--- a/.github/workflows/autofix.yml
+++ b/.github/workflows/autofix.yml
@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v4.0.0
+ uses: pnpm/action-setup@v4.1.0
- name: Install Node.js
uses: actions/setup-node@v4
diff --git a/.github/workflows/canary-minor.yml b/.github/workflows/canary-minor.yml
index b5d75b9ce..0b6401b8c 100644
--- a/.github/workflows/canary-minor.yml
+++ b/.github/workflows/canary-minor.yml
@@ -17,7 +17,7 @@ jobs:
ref: minor
- name: Install pnpm
- uses: pnpm/action-setup@v4.0.0
+ uses: pnpm/action-setup@v4.1.0
- name: Install Node.js
uses: actions/setup-node@v4
diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml
index bb622725a..71c794c70 100644
--- a/.github/workflows/canary.yml
+++ b/.github/workflows/canary.yml
@@ -15,7 +15,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v4.0.0
+ uses: pnpm/action-setup@v4.1.0
- name: Install Node.js
uses: actions/setup-node@v4
diff --git a/.github/workflows/size-data.yml b/.github/workflows/size-data.yml
index 7f8bf7b08..5a370b8b9 100644
--- a/.github/workflows/size-data.yml
+++ b/.github/workflows/size-data.yml
@@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v4.0.0
+ uses: pnpm/action-setup@v4.1.0
- name: Install Node.js
uses: actions/setup-node@v4
diff --git a/.github/workflows/size-report.yml b/.github/workflows/size-report.yml
index 0bfe4649e..66b5ad0ef 100644
--- a/.github/workflows/size-report.yml
+++ b/.github/workflows/size-report.yml
@@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v4.0.0
+ uses: pnpm/action-setup@v4.1.0
- name: Install Node.js
uses: actions/setup-node@v4
@@ -37,7 +37,7 @@ jobs:
run: pnpm install
- name: Download Size Data
- uses: dawidd6/action-download-artifact@v7
+ uses: dawidd6/action-download-artifact@v9
with:
name: size-data
run_id: ${{ github.event.workflow_run.id }}
@@ -56,7 +56,7 @@ jobs:
path: temp/size/base.txt
- name: Download Previous Size Data
- uses: dawidd6/action-download-artifact@v7
+ uses: dawidd6/action-download-artifact@v9
with:
branch: ${{ steps.pr-base.outputs.content }}
workflow: size-data.yml
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a520aa147..53c6a4679 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v4.0.0
+ uses: pnpm/action-setup@v4.1.0
- name: Install Node.js
uses: actions/setup-node@v4
@@ -35,7 +35,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v4.0.0
+ uses: pnpm/action-setup@v4.1.0
- name: Install Node.js
uses: actions/setup-node@v4
@@ -63,7 +63,7 @@ jobs:
key: chromium-${{ hashFiles('pnpm-lock.yaml') }}
- name: Install pnpm
- uses: pnpm/action-setup@v4.0.0
+ uses: pnpm/action-setup@v4.1.0
- name: Install Node.js
uses: actions/setup-node@v4
@@ -114,7 +114,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v4.0.0
+ uses: pnpm/action-setup@v4.1.0
- name: Install Node.js
uses: actions/setup-node@v4
diff --git a/.node-version b/.node-version
index 209e3ef4b..7d41c735d 100644
--- a/.node-version
+++ b/.node-version
@@ -1 +1 @@
-20
+22.14.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d45ad1087..2dbae4c79 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 afe5711e8..6b4935abd 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,8 @@ Please make sure to respect issue requirements and use [the new issue helper](ht
## Stay In Touch
-- [Twitter](https://twitter.com/vuejs)
+- [X](https://x.com/vuejs)
+- [Bluesky](https://bsky.app/profile/vuejs.org)
- [Blog](https://blog.vuejs.org/)
- [Job Board](https://vuejobs.com/?ref=vuejs)
@@ -44,7 +45,9 @@ Please make sure to read the [Contributing Guide](https://github.com/vuejs/core/
Thank you to all the people who already contributed to Vue!
-
+
+
+_Note: Showing the first 500 contributors only due to GitHub image size limitations_
## License
diff --git a/netlify.toml b/netlify.toml
index 277cc55a7..b7304df16 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -1,3 +1,3 @@
[build.environment]
- NODE_VERSION = "18"
+ NODE_VERSION = "22"
NPM_FLAGS = "--version" # prevent Netlify npm install
diff --git a/package.json b/package.json
index 2967aa4d4..266d47d06 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"private": true,
- "version": "3.5.13",
- "packageManager": "pnpm@9.15.4",
+ "version": "3.5.14",
+ "packageManager": "pnpm@10.9.0",
"type": "module",
"scripts": {
"dev": "node scripts/dev.js",
@@ -65,63 +65,52 @@
"@babel/parser": "catalog:",
"@babel/types": "catalog:",
"@rollup/plugin-alias": "^5.1.1",
- "@rollup/plugin-commonjs": "^28.0.2",
+ "@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-json": "^6.1.0",
- "@rollup/plugin-node-resolve": "^16.0.0",
+ "@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-replace": "5.0.4",
- "@swc/core": "^1.10.8",
+ "@swc/core": "^1.11.24",
"@types/hash-sum": "^1.0.2",
- "@types/node": "^22.10.7",
- "@types/semver": "^7.5.8",
+ "@types/node": "^22.14.1",
+ "@types/semver": "^7.7.0",
"@types/serve-handler": "^6.1.4",
- "@vitest/coverage-v8": "^3.0.2",
"@vitest/ui": "^3.0.2",
+ "@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.24.2",
+ "esbuild": "^0.25.4",
"esbuild-plugin-polyfill-node": "^0.3.0",
- "eslint": "^9.18.0",
- "eslint-plugin-import-x": "^4.6.1",
- "@vitest/eslint-plugin": "^1.1.25",
+ "eslint": "^9.25.1",
+ "eslint-plugin-import-x": "^4.11.0",
"estree-walker": "catalog:",
- "jsdom": "^26.0.0",
- "lint-staged": "^15.4.1",
+ "jsdom": "^26.1.0",
+ "lint-staged": "^15.5.1",
"lodash": "^4.17.21",
"magic-string": "^0.30.17",
"markdown-table": "^3.0.4",
"marked": "13.0.3",
"npm-run-all2": "^7.0.2",
"picocolors": "^1.1.1",
- "prettier": "^3.4.2",
+ "prettier": "^3.5.3",
"pretty-bytes": "^6.1.1",
"pug": "^3.0.3",
- "puppeteer": "~24.1.0",
+ "puppeteer": "~24.8.2",
"rimraf": "^6.0.1",
- "rollup": "^4.31.0",
- "rollup-plugin-dts": "^6.1.1",
- "rollup-plugin-esbuild": "^6.1.1",
+ "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.6.3",
+ "semver": "^7.7.1",
"serve": "^14.2.4",
"serve-handler": "^6.1.6",
- "simple-git-hooks": "^2.11.1",
+ "simple-git-hooks": "^2.13.0",
"todomvc-app-css": "^2.4.3",
"tslib": "^2.8.1",
"typescript": "~5.6.2",
- "typescript-eslint": "^8.20.0",
+ "typescript-eslint": "^8.31.1",
"vite": "catalog:",
- "vitest": "^3.0.2"
- },
- "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"
- }
- }
+ "vitest": "^3.1.3"
}
}
diff --git a/packages-private/dts-test/appDirective.test-d.ts b/packages-private/dts-test/appDirective.test-d.ts
index fb655a039..59101c22e 100644
--- a/packages-private/dts-test/appDirective.test-d.ts
+++ b/packages-private/dts-test/appDirective.test-d.ts
@@ -9,7 +9,7 @@ app.directive(
mounted(el, binding) {
expectType(el)
expectType(binding.value)
- expectType<{ prevent: boolean; stop: boolean }>(binding.modifiers)
+ expectType<{ prevent?: boolean; stop?: boolean }>(binding.modifiers)
expectType<'arg1' | 'arg2'>(binding.arg!)
// @ts-expect-error not any
diff --git a/packages-private/dts-test/appUse.test-d.ts b/packages-private/dts-test/appUse.test-d.ts
index 065f69568..21d702c9c 100644
--- a/packages-private/dts-test/appUse.test-d.ts
+++ b/packages-private/dts-test/appUse.test-d.ts
@@ -12,8 +12,11 @@ app.use(PluginWithoutType, 2)
app.use(PluginWithoutType, { anything: 'goes' }, true)
type PluginOptions = {
+ /** option1 */
option1?: string
+ /** option2 */
option2: number
+ /** option3 */
option3: boolean
}
@@ -25,6 +28,20 @@ const PluginWithObjectOptions = {
},
}
+const objectPluginOptional = {
+ install(app: App, options?: PluginOptions) {},
+}
+app.use(objectPluginOptional)
+app.use(
+ objectPluginOptional,
+ // Test JSDoc and `go to definition` for options
+ {
+ option1: 'foo',
+ option2: 1,
+ option3: true,
+ },
+)
+
for (const Plugin of [
PluginWithObjectOptions,
PluginWithObjectOptions.install,
@@ -92,7 +109,27 @@ const PluginTyped: Plugin = (app, options) => {}
// @ts-expect-error: needs options
app.use(PluginTyped)
-app.use(PluginTyped, { option2: 2, option3: true })
+app.use(
+ PluginTyped,
+ // Test autocomplete for options
+ {
+ option1: '',
+ option2: 2,
+ option3: true,
+ },
+)
+
+const functionPluginOptional = (app: App, options?: PluginOptions) => {}
+app.use(functionPluginOptional)
+app.use(functionPluginOptional, { option2: 2, option3: true })
+
+// type optional params
+const functionPluginOptional2: Plugin<[options?: PluginOptions]> = (
+ app,
+ options,
+) => {}
+app.use(functionPluginOptional2)
+app.use(functionPluginOptional2, { option2: 2, option3: true })
// vuetify usage
const key: string = ''
diff --git a/packages-private/dts-test/directives.test-d.ts b/packages-private/dts-test/directives.test-d.ts
index 5b87ebf71..6a478b673 100644
--- a/packages-private/dts-test/directives.test-d.ts
+++ b/packages-private/dts-test/directives.test-d.ts
@@ -29,7 +29,7 @@ describe('custom', () => {
value: number
oldValue: number | null
arg?: 'Arg'
- modifiers: Record<'a' | 'b', boolean>
+ modifiers: Partial>
}>(testDirective())
expectType<{
diff --git a/packages-private/dts-test/ref.test-d.ts b/packages-private/dts-test/ref.test-d.ts
index 89b80a70f..cf99b7bca 100644
--- a/packages-private/dts-test/ref.test-d.ts
+++ b/packages-private/dts-test/ref.test-d.ts
@@ -4,6 +4,7 @@ import {
type MaybeRefOrGetter,
type Ref,
type ShallowRef,
+ type TemplateRef,
type ToRefs,
type WritableComputedRef,
computed,
@@ -535,7 +536,7 @@ expectType(toValue(unref2))
// useTemplateRef
const tRef = useTemplateRef('foo')
-expectType>>(tRef)
+expectType(tRef)
const tRef2 = useTemplateRef('bar')
-expectType>>(tRef2)
+expectType>(tRef2)
diff --git a/packages-private/local-playground/tsconfig.json b/packages-private/local-playground/tsconfig.json
index 1b1d44c77..8ed981920 100644
--- a/packages-private/local-playground/tsconfig.json
+++ b/packages-private/local-playground/tsconfig.json
@@ -4,5 +4,5 @@
"isolatedDeclarations": false,
"allowJs": true
},
- "include": ["./**/*", "../packages/*/src"]
+ "include": ["./**/*", "../../packages/*/src"]
}
diff --git a/packages-private/sfc-playground/src/App.vue b/packages-private/sfc-playground/src/App.vue
index c05738611..92fe8e7b9 100644
--- a/packages-private/sfc-playground/src/App.vue
+++ b/packages-private/sfc-playground/src/App.vue
@@ -182,8 +182,9 @@ onMounted(() => {
body {
font-size: 13px;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
- Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ font-family:
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
+ Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
margin: 0;
--base: #444;
--nav-height: 50px;
diff --git a/packages-private/sfc-playground/src/download/download.ts b/packages-private/sfc-playground/src/download/download.ts
index 28d836edb..6b051abae 100644
--- a/packages-private/sfc-playground/src/download/download.ts
+++ b/packages-private/sfc-playground/src/download/download.ts
@@ -17,7 +17,10 @@ export async function downloadProject(store: ReplStore) {
// basic structure
zip.file('index.html', index)
- zip.file('package.json', pkg)
+ zip.file(
+ 'package.json',
+ pkg.replace(`"vue": "latest"`, `"vue": "${store.vueVersion || 'latest'}"`),
+ )
zip.file('vite.config.js', config)
zip.file('README.md', readme)
diff --git a/packages-private/sfc-playground/src/download/template/package.json b/packages-private/sfc-playground/src/download/template/package.json
index c7f318d1c..b9bb278ed 100644
--- a/packages-private/sfc-playground/src/download/template/package.json
+++ b/packages-private/sfc-playground/src/download/template/package.json
@@ -8,10 +8,10 @@
"serve": "vite preview"
},
"dependencies": {
- "vue": "^3.4.0"
+ "vue": "latest"
},
"devDependencies": {
- "@vitejs/plugin-vue": "^5.2.1",
- "vite": "^6.0.7"
+ "@vitejs/plugin-vue": "^5.2.4",
+ "vite": "^6.3.5"
}
}
diff --git a/packages-private/template-explorer/style.css b/packages-private/template-explorer/style.css
index 93f6f623c..eed9e18a0 100644
--- a/packages-private/template-explorer/style.css
+++ b/packages-private/template-explorer/style.css
@@ -1,8 +1,9 @@
body {
margin: 0;
overflow: hidden;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
- Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ font-family:
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
+ Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--bg: #1d1f21;
--border: #333;
}
diff --git a/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts b/packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts
index ab5ed7bae..358c0e31c 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 d2f474c59..7311f4693 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/index.ts b/packages/compiler-core/src/index.ts
index 36ed73eab..e54b0c3a4 100644
--- a/packages/compiler-core/src/index.ts
+++ b/packages/compiler-core/src/index.ts
@@ -17,6 +17,7 @@ export {
createTransformContext,
traverseNode,
createStructuralDirectiveTransform,
+ getSelfName,
type NodeTransform,
type StructuralDirectiveTransform,
type DirectiveTransform,
diff --git a/packages/compiler-core/src/parser.ts b/packages/compiler-core/src/parser.ts
index 95c5e129f..7d1b01360 100644
--- a/packages/compiler-core/src/parser.ts
+++ b/packages/compiler-core/src/parser.ts
@@ -388,7 +388,7 @@ const tokenizer = new Tokenizer(stack, {
CompilerDeprecationTypes.COMPILER_V_BIND_SYNC,
currentOptions,
currentProp.loc,
- currentProp.rawName,
+ currentProp.arg!.loc.source,
)
) {
currentProp.name = 'model'
diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts
index aeb96cc2b..7d35ec9f7 100644
--- a/packages/compiler-core/src/transform.ts
+++ b/packages/compiler-core/src/transform.ts
@@ -123,6 +123,11 @@ export interface TransformContext
filters?: Set
}
+export function getSelfName(filename: string): string | null {
+ const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/)
+ return nameMatch ? capitalize(camelize(nameMatch[1])) : null
+}
+
export function createTransformContext(
root: RootNode,
{
@@ -150,11 +155,10 @@ export function createTransformContext(
compatConfig,
}: TransformOptions,
): TransformContext {
- const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/)
const context: TransformContext = {
// options
filename,
- selfName: nameMatch && capitalize(camelize(nameMatch[1])),
+ selfName: getSelfName(filename),
prefixIdentifiers,
hoistStatic,
hmr,
diff --git a/packages/compiler-core/src/transforms/cacheStatic.ts b/packages/compiler-core/src/transforms/cacheStatic.ts
index 8d5961643..e5d673806 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 db367f39c..28625439a 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 1be062a27..18745d386 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 d8ce62ecd..fd34e7a32 100644
--- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap
@@ -196,6 +196,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 e58aed1d3..5709cfbe5 100644
--- a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
@@ -360,6 +360,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(`