diff --git a/.github/commit-convention.md b/.github/commit-convention.md index d17a8bd4fc9..11a64576a24 100644 --- a/.github/commit-convention.md +++ b/.github/commit-convention.md @@ -44,7 +44,7 @@ This reverts commit 667ecc1654a317a13331b17617d973392f415f02. ### Full Message Format -A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**: +A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**: ``` (): @@ -74,9 +74,9 @@ The scope could be anything specifying the place of the commit change. For examp The subject contains a succinct description of the change: -* use the imperative, present tense: "change" not "changed" nor "changes" -* don't capitalize the first letter -* no dot (.) at the end +- use the imperative, present tense: "change" not "changed" nor "changes" +- don't capitalize the first letter +- no dot (.) at the end ### Body diff --git a/.github/contributing.md b/.github/contributing.md index 3ed1de4e02a..2554582b887 100644 --- a/.github/contributing.md +++ b/.github/contributing.md @@ -35,7 +35,6 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before Another aspect of it is that large scale stylistic changes result in massive diffs that touch multiple files, adding noise to the git history and makes tracing behavior changes across commits more cumbersome. - ### Pull Request Checklist - Vue core has two primary work branches: `main` and `minor`. @@ -237,7 +236,7 @@ Tests that test against source code are grouped under `nr test-unit`, while test ### `nr test-dts` -Runs `nr build-dts` first, then verify the type tests in `packages/dts-test` are working correctly against the actual built type declarations. +Runs `nr build-dts` first, then verify the type tests in `packages-private/dts-test` are working correctly against the actual built type declarations. ## Project Structure @@ -336,7 +335,7 @@ Test coverage is continuously deployed at https://coverage.vuejs.org. PRs that i ### Testing Type Definition Correctness -Type tests are located in the `packages/dts-test` directory. To run the dts tests, run `nr test-dts`. Note that the type test requires all relevant `*.d.ts` files to be built first (and the script does it for you). Once the `d.ts` files are built and up-to-date, the tests can be re-run by running `nr test-dts-only`. +Type tests are located in the `packages-private/dts-test` directory. To run the dts tests, run `nr test-dts`. Note that the type test requires all relevant `*.d.ts` files to be built first (and the script does it for you). Once the `d.ts` files are built and up-to-date, the tests can be re-run by running `nr test-dts-only`. ## Financial Contribution diff --git a/.github/maintenance.md b/.github/maintenance.md index 8d4317c6b01..b1fb550dd7a 100644 --- a/.github/maintenance.md +++ b/.github/maintenance.md @@ -80,6 +80,7 @@ Depending on the type of the PR, different considerations need to be taken into - Make sure it doesn't accidentally cause dev-only or compiler-only code branches to be included in the runtime build. Notable case is that some functions in @vue/shared are compiler-only and should not be used in runtime code, e.g. `isHTMLTag` and `isSVGTag`. - Performance + - Be careful about code changes in "hot paths", in particular the Virtual DOM renderer (`runtime-core/src/renderer.ts`) and component instantiation code. - Potential Breakage diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 9c04587027d..8808b599e62 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -17,8 +17,8 @@ { groupName: 'playground', matchFileNames: [ - 'packages/sfc-playground/package.json', - 'packages/template-explorer/package.json', + 'packages-private/sfc-playground/package.json', + 'packages-private/template-explorer/package.json', ], }, { @@ -54,5 +54,13 @@ // pinned // https://github.com/vuejs/core/commit/a012e39b373f1b6918e5c89856e8f902e1bfa14d '@rollup/plugin-replace', + + // pinned + // only used in example for e2e tests + 'marked', + + // pinned, 5.0+ has exports issues + // https://github.com/vuejs/core/issues/11603 + 'entities', ], } diff --git a/.github/workflows/canary-minor.yml b/.github/workflows/canary-minor.yml index ffb9b384d4e..b5d75b9cebb 100644 --- a/.github/workflows/canary-minor.yml +++ b/.github/workflows/canary-minor.yml @@ -28,6 +28,6 @@ jobs: - run: pnpm install - - run: pnpm release --canary --tag minor + - run: pnpm release --canary --publish --tag minor env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index a9432ced059..bb622725aa8 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -26,6 +26,6 @@ jobs: - run: pnpm install - - run: pnpm release --canary + - run: pnpm release --canary --publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d707bae2d3..c8c217f62c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,141 +3,40 @@ on: push: branches: - '**' + tags: + - '!**' pull_request: branches: - main - minor -permissions: - contents: read # to fetch code (actions/checkout) - jobs: - unit-test: - runs-on: ubuntu-latest - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - env: - PUPPETEER_SKIP_DOWNLOAD: 'true' - steps: - - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4.0.0 - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - - run: pnpm install - - - name: Run unit tests - run: pnpm run test-unit - - unit-test-windows: - runs-on: windows-latest - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - env: - PUPPETEER_SKIP_DOWNLOAD: 'true' - steps: - - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4.0.0 - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - - run: pnpm install + test: + if: ${{ ! startsWith(github.event.head_commit.message, 'release:') && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) }} + uses: ./.github/workflows/test.yml - - name: Run compiler unit tests - run: pnpm run test-unit compiler - - - name: Run ssr unit tests - run: pnpm run test-unit server-renderer - - e2e-test: - runs-on: ubuntu-latest - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - steps: - - uses: actions/checkout@v4 - - - name: Setup cache for Chromium binary - uses: actions/cache@v4 - with: - path: ~/.cache/puppeteer - key: chromium-${{ hashFiles('pnpm-lock.yaml') }} - - - name: Install pnpm - uses: pnpm/action-setup@v4.0.0 - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - - run: pnpm install - - run: node node_modules/puppeteer/install.mjs - - - name: Run e2e tests - run: pnpm run test-e2e - - - name: verify treeshaking - run: node scripts/verify-treeshaking.js - - lint-and-test-dts: + continuous-release: + if: github.repository == 'vuejs/core' runs-on: ubuntu-latest - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - env: - PUPPETEER_SKIP_DOWNLOAD: 'true' steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 - name: Install pnpm - uses: pnpm/action-setup@v4.0.0 + uses: pnpm/action-setup@v4 - name: Install Node.js uses: actions/setup-node@v4 with: node-version-file: '.node-version' + registry-url: 'https://registry.npmjs.org' cache: 'pnpm' - - run: pnpm install - - - name: Run eslint - run: pnpm run lint - - - name: Run prettier - run: pnpm run format-check - - - name: Run type declaration tests - run: pnpm run test-dts - - # benchmarks: - # runs-on: ubuntu-latest - # if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - # env: - # PUPPETEER_SKIP_DOWNLOAD: 'true' - # steps: - # - uses: actions/checkout@v4 - - # - name: Install pnpm - # uses: pnpm/action-setup@v3.0.0 - - # - name: Install Node.js - # uses: actions/setup-node@v4 - # with: - # node-version-file: '.node-version' - # cache: 'pnpm' + - name: Install deps + run: pnpm install - # - run: pnpm install + - name: Build + run: pnpm build --withTypes - # - name: Run benchmarks - # uses: CodSpeedHQ/action@v2 - # with: - # run: pnpm vitest bench --run - # token: ${{ secrets.CODSPEED_TOKEN }} + - name: Release + run: pnpx pkg-pr-new publish --compact --pnpm './packages/*' diff --git a/.github/workflows/close-cant-reproduce-issues.yml b/.github/workflows/close-cant-reproduce-issues.yml new file mode 100644 index 00000000000..8fb48f842d8 --- /dev/null +++ b/.github/workflows/close-cant-reproduce-issues.yml @@ -0,0 +1,21 @@ +name: Auto close issues with "can't reproduce" label + +on: + schedule: + - cron: '0 0 * * *' + +permissions: + issues: write + +jobs: + close-issues: + if: github.repository == 'vuejs/core' + runs-on: ubuntu-latest + steps: + - name: can't reproduce + uses: actions-cool/issues-helper@v3 + with: + actions: 'close-issues' + token: ${{ secrets.GITHUB_TOKEN }} + labels: "can't reproduce" + inactive-day: 3 diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml index 25adf7c85f4..b3e963ececa 100644 --- a/.github/workflows/ecosystem-ci-trigger.yml +++ b/.github/workflows/ecosystem-ci-trigger.yml @@ -9,7 +9,8 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'vuejs/core' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/ecosystem-ci run') steps: - - uses: actions/github-script@v7 + - name: Check user permission + uses: actions/github-script@v7 with: script: | const user = context.payload.sender.login @@ -43,7 +44,8 @@ jobs: }) throw new Error('not allowed') } - - uses: actions/github-script@v7 + - name: Get PR info + uses: actions/github-script@v7 id: get-pr-data with: script: | @@ -56,9 +58,11 @@ jobs: return { num: context.issue.number, branchName: pr.head.ref, - repo: pr.head.repo.full_name + repo: pr.head.repo.full_name, + commit: pr.head.sha } - - uses: actions/github-script@v7 + - name: Trigger run + uses: actions/github-script@v7 id: trigger env: COMMENT: ${{ github.event.comment.body }} @@ -80,6 +84,7 @@ jobs: prNumber: '' + prData.num, branchName: prData.branchName, repo: prData.repo, - suite: suite === '' ? '-' : suite + suite: suite === '' ? '-' : suite, + commit: prData.commit } }) diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml deleted file mode 100644 index d93510607a9..00000000000 --- a/.github/workflows/release-tag.yml +++ /dev/null @@ -1,28 +0,0 @@ -on: - push: - tags: - - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 - -name: Create Release - -permissions: {} -jobs: - build: - permissions: - contents: write # to create release (yyx990803/release-tag) - - name: Create Release - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@master - - name: Create Release for Tag - id: release_tag - uses: yyx990803/release-tag@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - body: | - For stable releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/main/CHANGELOG.md) for details. - For pre-releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/minor/CHANGELOG.md) of the `minor` branch. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000000..c260a728e71 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,55 @@ +name: Release + +on: + push: + tags: + - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 + +jobs: + test: + uses: ./.github/workflows/test.yml + + release: + # prevents this action from running on forks + if: github.repository == 'vuejs/core' + needs: [test] + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + # Use Release environment for deployment protection + environment: Release + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - name: Install deps + run: pnpm install + + - name: Build and publish + id: publish + run: | + pnpm release --publishOnly + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Create GitHub release + id: release_tag + uses: yyx990803/release-tag@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + body: | + For stable releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/main/CHANGELOG.md) for details. + For pre-releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/minor/CHANGELOG.md) of the `minor` branch. diff --git a/.github/workflows/size-data.yml b/.github/workflows/size-data.yml index a702d0fef90..7f8bf7b08ca 100644 --- a/.github/workflows/size-data.yml +++ b/.github/workflows/size-data.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - minor pull_request: branches: - main @@ -17,6 +18,7 @@ env: jobs: upload: + if: github.repository == 'vuejs/core' runs-on: ubuntu-latest steps: @@ -36,18 +38,14 @@ jobs: - run: pnpm run size + - name: Save PR number & base branch + if: ${{github.event_name == 'pull_request'}} + run: | + echo ${{ github.event.number }} > ./temp/size/number.txt + echo ${{ github.base_ref }} > ./temp/size/base.txt + - name: Upload Size Data uses: actions/upload-artifact@v4 with: name: size-data path: temp/size - - - name: Save PR number - if: ${{github.event_name == 'pull_request'}} - run: echo ${{ github.event.number }} > ./pr.txt - - - uses: actions/upload-artifact@v4 - if: ${{github.event_name == 'pull_request'}} - with: - name: pr-number - path: pr.txt diff --git a/.github/workflows/size-report.yml b/.github/workflows/size-report.yml index 5cec662874e..d8d0c416a67 100644 --- a/.github/workflows/size-report.yml +++ b/.github/workflows/size-report.yml @@ -18,6 +18,7 @@ jobs: size-report: runs-on: ubuntu-latest if: > + github.repository == 'vuejs/core' && github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' steps: @@ -35,30 +36,29 @@ jobs: - name: Install dependencies run: pnpm install - - name: Download PR number + - name: Download Size Data uses: dawidd6/action-download-artifact@v6 with: - name: pr-number + name: size-data run_id: ${{ github.event.workflow_run.id }} - path: /tmp/pr-number + path: temp/size - name: Read PR Number id: pr-number uses: juliangruber/read-file-action@v1 with: - path: /tmp/pr-number/pr.txt + path: temp/size/number.txt - - name: Download Size Data - uses: dawidd6/action-download-artifact@v6 + - name: Read base branch + id: pr-base + uses: juliangruber/read-file-action@v1 with: - name: size-data - run_id: ${{ github.event.workflow_run.id }} - path: temp/size + path: temp/size/base.txt - name: Download Previous Size Data uses: dawidd6/action-download-artifact@v6 with: - branch: main + branch: ${{ steps.pr-base.outputs.content }} workflow: size-data.yml event: push name: size-data diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000000..70dc8224813 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,108 @@ +name: 'test' + +on: workflow_call + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + unit-test: + runs-on: ubuntu-latest + env: + PUPPETEER_SKIP_DOWNLOAD: 'true' + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4.0.0 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + + - run: pnpm install + + - name: Run unit tests + run: pnpm run test-unit + + unit-test-windows: + runs-on: windows-latest + env: + PUPPETEER_SKIP_DOWNLOAD: 'true' + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4.0.0 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + + - run: pnpm install + + - name: Run compiler unit tests + run: pnpm run test-unit compiler + + - name: Run ssr unit tests + run: pnpm run test-unit server-renderer + + e2e-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup cache for Chromium binary + uses: actions/cache@v4 + with: + path: ~/.cache/puppeteer + key: chromium-${{ hashFiles('pnpm-lock.yaml') }} + + - name: Install pnpm + uses: pnpm/action-setup@v4.0.0 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + + - run: pnpm install + - run: node node_modules/puppeteer/install.mjs + + - name: Run e2e tests + run: pnpm run test-e2e + + - name: verify treeshaking + run: node scripts/verify-treeshaking.js + + lint-and-test-dts: + runs-on: ubuntu-latest + env: + PUPPETEER_SKIP_DOWNLOAD: 'true' + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4.0.0 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + + - run: pnpm install + + - name: Run eslint + run: pnpm run lint + + - name: Run prettier + run: pnpm run format-check + + - name: Run type declaration tests + run: pnpm run test-dts diff --git a/.prettierignore b/.prettierignore index fbd3dca8ca3..ca3c40849fd 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,3 @@ dist -*.md -*.html pnpm-lock.yaml +CHANGELOG*.md diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000000..91ebd56925c --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["vitest.explorer"] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d5e5a1ea4..8902666d1f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,983 +1,193 @@ -## [3.4.35](https://github.com/vuejs/core/compare/v3.4.34...v3.4.35) (2024-07-31) +# [3.5.0-rc.1](https://github.com/vuejs/core/compare/v3.5.0-beta.3...v3.5.0-rc.1) (2024-08-29) ### Bug Fixes -* **teleport/ssr:** fix Teleport hydration regression due to targetStart anchor addition ([7b18cdb](https://github.com/vuejs/core/commit/7b18cdb0b53a94007ca6a3675bf41b5d3153fec6)) -* **teleport/ssr:** ensure targetAnchor and targetStart not null during hydration ([#11456](https://github.com/vuejs/core/issues/11456)) ([12667da](https://github.com/vuejs/core/commit/12667da4879f980dcf2c50e36f3642d085a87d71)), closes [#11400](https://github.com/vuejs/core/issues/11400) -* **types/ref:** allow getter and setter types to be unrelated ([#11442](https://github.com/vuejs/core/issues/11442)) ([e0b2975](https://github.com/vuejs/core/commit/e0b2975ef65ae6a0be0aa0a0df43fb887c665251)) +* **compiler-sfc:** skip circular tsconfig project reference ([#11680](https://github.com/vuejs/core/issues/11680)) ([9c4c2e5](https://github.com/vuejs/core/commit/9c4c2e51b045218d0c5ca64b4fb58b17d5d580cc)), closes [#11382](https://github.com/vuejs/core/issues/11382) +* **custom-element:** handle keys set on custom elements ([#11655](https://github.com/vuejs/core/issues/11655)) ([f1d1831](https://github.com/vuejs/core/commit/f1d1831f07fe52d5681a5ec9ec310572463abf26)), closes [#11641](https://github.com/vuejs/core/issues/11641) +* **deps:** update dependency monaco-editor to ^0.51.0 ([#11713](https://github.com/vuejs/core/issues/11713)) ([434f8a9](https://github.com/vuejs/core/commit/434f8a97c77f68aeae050e9e4e1f54f63bc4bd26)) +* **keep-alive:** reset keep alive flag when the component is removed from include ([#11718](https://github.com/vuejs/core/issues/11718)) ([29c321b](https://github.com/vuejs/core/commit/29c321bfd33f9197244dec3d027077e63b2cdf2f)), closes [#11717](https://github.com/vuejs/core/issues/11717) +* **reactivity:** avoid infinite recursion when mutating ref wrapped in reactive ([313e4bf](https://github.com/vuejs/core/commit/313e4bf55214ac1e334a99c329a3ba5daca4f156)), closes [#11696](https://github.com/vuejs/core/issues/11696) +* **reactivity:** ensure watcher with once: true are properly removed from effect scope ([#11665](https://github.com/vuejs/core/issues/11665)) ([fbc0c42](https://github.com/vuejs/core/commit/fbc0c42bcf6dea5a6ae664223fa19d4375ca39f0)) +* **runtime-dom:** setting innerHTML when patching props should go through trusted types ([d875de5](https://github.com/vuejs/core/commit/d875de54e9e03e0768fe550aa4c4886a4baf3bd7)) +* **types:** GlobalDirective / GlobalComponents should not be records ([42e8df6](https://github.com/vuejs/core/commit/42e8df62030e7f2c287d9103f045e67b34a63e3b)) -### Performance Improvements - -* **runtime-core:** improve efficiency of normalizePropsOptions ([#11409](https://github.com/vuejs/core/issues/11409)) ([5680142](https://github.com/vuejs/core/commit/5680142e68096c42e66da9f4c6220d040d7c56ba)), closes [#9739](https://github.com/vuejs/core/issues/9739) - - - -## [3.4.34](https://github.com/vuejs/core/compare/v3.4.33...v3.4.34) (2024-07-24) - - -### Bug Fixes - -* **defineModel:** correct update with multiple changes in same tick ([#11430](https://github.com/vuejs/core/issues/11430)) ([a18f1ec](https://github.com/vuejs/core/commit/a18f1ecf05842337f1eb39a6871adb8cb4024093)), closes [#11429](https://github.com/vuejs/core/issues/11429) - - - -## [3.4.33](https://github.com/vuejs/core/compare/v3.4.32...v3.4.33) (2024-07-19) - - -### Bug Fixes - -* **runtime-dom:** handle undefined values in v-html ([#11403](https://github.com/vuejs/core/issues/11403)) ([5df67e3](https://github.com/vuejs/core/commit/5df67e36756639ea7b923d1b139d6cb14450123b)) - - - -## [3.4.32](https://github.com/vuejs/core/compare/v3.4.31...v3.4.32) (2024-07-17) - - -### Bug Fixes - -* **build:** use consistent minify options from previous terser config ([789675f](https://github.com/vuejs/core/commit/789675f65d2b72cf979ba6a29bd323f716154a4b)) -* **compiler-sfc:** correctly resolve type annotation for declared function ([#11279](https://github.com/vuejs/core/issues/11279)) ([b287aee](https://github.com/vuejs/core/commit/b287aeec3ea85f20e4b1fc3d907c901bdc2a0176)), closes [#11266](https://github.com/vuejs/core/issues/11266) -* **defineModel:** force local update when setter results in same emitted value ([de174e1](https://github.com/vuejs/core/commit/de174e1aa756508c7542605a448e55a373afb1ed)), closes [#10279](https://github.com/vuejs/core/issues/10279) [#10301](https://github.com/vuejs/core/issues/10301) -* **hmr:** hmr reload should work with async component ([#11248](https://github.com/vuejs/core/issues/11248)) ([c8b9794](https://github.com/vuejs/core/commit/c8b97945759e869c997d60c3350d2451c5ff7887)) -* **hydration:** fix tracking of reactive style objects in production ([c10e40a](https://github.com/vuejs/core/commit/c10e40a217b89ab7e0f7f3515242d4246ecffbdd)), closes [#11372](https://github.com/vuejs/core/issues/11372) -* **hydration:** handle consectuvie text nodes during hydration ([f44c3b3](https://github.com/vuejs/core/commit/f44c3b37d446d5f8e34539029dae0d806b25bb47)), closes [#7285](https://github.com/vuejs/core/issues/7285) [#7301](https://github.com/vuejs/core/issues/7301) -* **reactivity:** ensure `unref` correctly resolves type for `ShallowRef` ([#11360](https://github.com/vuejs/core/issues/11360)) ([a509e30](https://github.com/vuejs/core/commit/a509e30f059fcdd158f39fdf34670b1019eaf2d1)), closes [#11356](https://github.com/vuejs/core/issues/11356) -* **reactivity:** shallowReactive map "unwraps" the nested refs ([#8503](https://github.com/vuejs/core/issues/8503)) ([50ddafe](https://github.com/vuejs/core/commit/50ddafe91b9195cf94124466239f82c9794699fb)), closes [#8501](https://github.com/vuejs/core/issues/8501) [#11249](https://github.com/vuejs/core/issues/11249) -* **runtime-core:** avoid recursive warning ([3ee7b4c](https://github.com/vuejs/core/commit/3ee7b4c7b1374c5bdc50a579b49f6bc15022b085)), closes [#8074](https://github.com/vuejs/core/issues/8074) -* **runtime-core:** bail manually rendered compiler slot fragments in all cases ([3d34f40](https://github.com/vuejs/core/commit/3d34f406ac7497dafd2f4e62ab23579b78a0e08a)), closes [#10870](https://github.com/vuejs/core/issues/10870) -* **runtime-core:** do not emit when defineModel ref is set with same value ([#11162](https://github.com/vuejs/core/issues/11162)) ([f1bb0ae](https://github.com/vuejs/core/commit/f1bb0aef084b5cdd4d49aecfed01ec106d9b6897)), closes [#11125](https://github.com/vuejs/core/issues/11125) -* **runtime-core:** errors during component patch should be caught by error handlers ([ee0248a](https://github.com/vuejs/core/commit/ee0248accff589a94688e177e5e3af10c18288cb)) -* **runtime-core:** force diff slot fallback content and provided content ([d76dd9c](https://github.com/vuejs/core/commit/d76dd9c58de24b273bc55af3a8ed81ba693e9683)), closes [#7256](https://github.com/vuejs/core/issues/7256) [#9200](https://github.com/vuejs/core/issues/9200) [#9308](https://github.com/vuejs/core/issues/9308) [#7266](https://github.com/vuejs/core/issues/7266) [#9213](https://github.com/vuejs/core/issues/9213) -* **runtime-core:** more edge case fix for manually rendered compiled slot ([685e3f3](https://github.com/vuejs/core/commit/685e3f381c024b9f4023e60fe0545dc60d90d984)), closes [#11336](https://github.com/vuejs/core/issues/11336) -* **runtime-core:** use separate prop caches for components and mixins ([#11350](https://github.com/vuejs/core/issues/11350)) ([b0aa234](https://github.com/vuejs/core/commit/b0aa234e5e7a611c018de68bc31e0cf55518d5ce)), closes [#7998](https://github.com/vuejs/core/issues/7998) -* **runtime-dom:** properly handle innerHTML unmount into new children ([#11159](https://github.com/vuejs/core/issues/11159)) ([3e9e32e](https://github.com/vuejs/core/commit/3e9e32ee0a6d0fbf67e9098a66ff0a1ea6647806)), closes [#9135](https://github.com/vuejs/core/issues/9135) -* **teleport:** skip teleported nodes when locating patch anchor ([8655ced](https://github.com/vuejs/core/commit/8655ced480ea0fe453ff5fe445cecf97b91ec260)), closes [#9071](https://github.com/vuejs/core/issues/9071) [#9134](https://github.com/vuejs/core/issues/9134) [#9313](https://github.com/vuejs/core/issues/9313) [#9313](https://github.com/vuejs/core/issues/9313) -* **v-model:** component v-model modifiers trim and number when cases don't match ([#9609](https://github.com/vuejs/core/issues/9609)) ([7fb6eb8](https://github.com/vuejs/core/commit/7fb6eb882b64bf99a99d00606e54b0e050674206)), closes [#4848](https://github.com/vuejs/core/issues/4848) [#4850](https://github.com/vuejs/core/issues/4850) [#4850](https://github.com/vuejs/core/issues/4850) -* **v-once:** properly unmount v-once cached trees ([d343a0d](https://github.com/vuejs/core/commit/d343a0dc01663f91db42b4ddb693e6fffcb45873)), closes [#5154](https://github.com/vuejs/core/issues/5154) [#8809](https://github.com/vuejs/core/issues/8809) - - -### Performance Improvements - -* **server-renderer:** avoid unnecessary checks in `createBuffer` ([#11364](https://github.com/vuejs/core/issues/11364)) ([fc205bf](https://github.com/vuejs/core/commit/fc205bf4decde5ce0f4a61394ffa3914b502c287)) -* **server-renderer:** optimize `unrollBuffer` by avoiding promises ([#11340](https://github.com/vuejs/core/issues/11340)) ([05779a7](https://github.com/vuejs/core/commit/05779a70bd0b567ae458a07636d229bd07c44c4e)) - - - -## [3.4.31](https://github.com/vuejs/core/compare/v3.4.30...v3.4.31) (2024-06-28) - - -### Bug Fixes - -* **compiler-core:** handle inline comments with undefined bindings ([#11217](https://github.com/vuejs/core/issues/11217)) ([746352a](https://github.com/vuejs/core/commit/746352a14d62e9d3d9a38c359d2c54d418c1e0ac)), closes [#11216](https://github.com/vuejs/core/issues/11216) -* **shared:** unwrap refs in toDisplayString ([#7306](https://github.com/vuejs/core/issues/7306)) ([0126cff](https://github.com/vuejs/core/commit/0126cfff9d93bcec70e5745519f6378e3cd3f39c)), closes [#5578](https://github.com/vuejs/core/issues/5578) [#5593](https://github.com/vuejs/core/issues/5593) [#11199](https://github.com/vuejs/core/issues/11199) [#11201](https://github.com/vuejs/core/issues/11201) - - -### Reverts - -* Revert "fix(reactivity): avoid infinite loop when render access a side effect computed ([#11135](https://github.com/vuejs/core/issues/11135))" ([e0df985](https://github.com/vuejs/core/commit/e0df985f0317fb65c5b461bf224375c7763f0269)) -* Revert "fix(reactivity): fix side effect computed dirty level (#11183)" ([6c303ea](https://github.com/vuejs/core/commit/6c303eacd14b7b0de0accc228f6abeb43d706f63)), closes [#11183](https://github.com/vuejs/core/issues/11183) - - - -## [3.4.30](https://github.com/vuejs/core/compare/v3.4.29...v3.4.30) (2024-06-22) - -**Note: this release contains a fix (#11150) that requires `vue-tsc` to also be updated in sync to ^2.0.22. See #11196** - -### Bug Fixes - -* **compiler-core:** should not remove slot node with `v-else` ([#11150](https://github.com/vuejs/core/issues/11150)) ([e102670](https://github.com/vuejs/core/commit/e102670bde00417c3a5b0262c855b297c0e4169e)) -* **hydration:** fix css vars hydration mismatch false positive on attr-fallthrough ([#11190](https://github.com/vuejs/core/issues/11190)) ([7ad67ce](https://github.com/vuejs/core/commit/7ad67ced26e5f53a47cb42f4834496e4958cb53b)), closes [#11188](https://github.com/vuejs/core/issues/11188) -* **hydration:** skip prop mismatch check for directives that mutate DOM in created ([3169c91](https://github.com/vuejs/core/commit/3169c914939d02a013b2938aff30dac8525923f8)), closes [#11189](https://github.com/vuejs/core/issues/11189) -* **reactivity:** fix side effect computed dirty level ([#11183](https://github.com/vuejs/core/issues/11183)) ([3bd79e3](https://github.com/vuejs/core/commit/3bd79e3e5ed960fc42cbf77bc61a97d2c03557c0)), closes [#11181](https://github.com/vuejs/core/issues/11181) [#11169](https://github.com/vuejs/core/issues/11169) -* **runtime-core:** ensure unmount dynamic components in optimized mode ([#11171](https://github.com/vuejs/core/issues/11171)) ([220fe24](https://github.com/vuejs/core/commit/220fe247484209e62c7f4991902c5335e29c5007)), closes [#11168](https://github.com/vuejs/core/issues/11168) -* **runtime-core:** update devtool __vnode on patch, avoid memory leak during dev ([a959781](https://github.com/vuejs/core/commit/a959781dd6f609dcb6f16dd7fa47d3b16895e5ca)), closes [#11192](https://github.com/vuejs/core/issues/11192) -* **runtime-dom:** ensure only symbols are explicitly stringified during attribute patching ([#11182](https://github.com/vuejs/core/issues/11182)) ([a2e35d6](https://github.com/vuejs/core/commit/a2e35d682db15a592f4270bb0cde70a0e7bdc4a6)), closes [#11177](https://github.com/vuejs/core/issues/11177) -* **runtime-dom:** prevent setting state as attribute for custom elements ([#11165](https://github.com/vuejs/core/issues/11165)) ([8ae4c29](https://github.com/vuejs/core/commit/8ae4c293adcec28f18114cb6016230a86787e6a9)), closes [#11163](https://github.com/vuejs/core/issues/11163) - - -### Performance Improvements - -* **reactivity:** cache tracking value ([#11145](https://github.com/vuejs/core/issues/11145)) ([7936dae](https://github.com/vuejs/core/commit/7936daebceab2ae9461c3b8f256e51020fb7d3ed)) - - - -## [3.4.29](https://github.com/vuejs/core/compare/v3.4.28...v3.4.29) (2024-06-14) - - -### Bug Fixes - -* **build:** fix accidental inclusion of runtime-core in server-renderer cjs build ([11cc12b](https://github.com/vuejs/core/commit/11cc12b915edfe0e4d3175e57464f73bc2c1cb04)), closes [#11137](https://github.com/vuejs/core/issues/11137) -* **compiler-sfc:** fix missing scope for extends error message ([4ec387b](https://github.com/vuejs/core/commit/4ec387b100985b008cdcc4cd883a5b6328c05766)) -* **compiler-sfc:** fix parsing of mts, d.mts, and mtsx files ([a476692](https://github.com/vuejs/core/commit/a476692ed2d7308f2742d8ff3554cf97a392b0b7)) -* **compiler-sfc:** support [@vue-ignore](https://github.com/vue-ignore) comment on more type sources ([a23e99b](https://github.com/vuejs/core/commit/a23e99bedf1d65841d162951f10ce35b907a5680)) -* **custom-element:** support same direct setup function signature in defineCustomElement ([7c8b126](https://github.com/vuejs/core/commit/7c8b12620aad4969b8dc4944d4fc486d16c3033c)), closes [#11116](https://github.com/vuejs/core/issues/11116) -* **reactivity:** avoid infinite loop when render access a side effect computed ([#11135](https://github.com/vuejs/core/issues/11135)) ([8296e19](https://github.com/vuejs/core/commit/8296e19855e369a7826f5ea26540a6da01dc7093)), closes [#11121](https://github.com/vuejs/core/issues/11121) - - - -## [3.4.28](https://github.com/vuejs/core/compare/v3.4.27...v3.4.28) (2024-06-14) - - -### Bug Fixes - -* **compat:** correctly transform non-identifier expressions in legacy filter syntax ([#10896](https://github.com/vuejs/core/issues/10896)) ([07b3c4b](https://github.com/vuejs/core/commit/07b3c4b7860009e19446f3d78571556c5737d82a)), closes [#10852](https://github.com/vuejs/core/issues/10852) -* **compat:** ensure proper handling of render fuction from SFC using Vue.extend ([#7781](https://github.com/vuejs/core/issues/7781)) ([c73847f](https://github.com/vuejs/core/commit/c73847f2becc20f03cb9c68748eea92455e688ee)), closes [#7766](https://github.com/vuejs/core/issues/7766) -* **compat:** only warn ATTR_FALSE_VALUE when enabled ([04729ba](https://github.com/vuejs/core/commit/04729ba2163d840f0ca7866bc964696eb5557804)), closes [#11126](https://github.com/vuejs/core/issues/11126) -* **compile-sfc:** register props destructure rest id as setup bindings ([#10888](https://github.com/vuejs/core/issues/10888)) ([b2b5f57](https://github.com/vuejs/core/commit/b2b5f57c2c945edd0eebc1b545ec1b7568e51484)), closes [#10885](https://github.com/vuejs/core/issues/10885) -* **compile-sfc:** Support project reference with folder, ([#10908](https://github.com/vuejs/core/issues/10908)) ([bdeac37](https://github.com/vuejs/core/commit/bdeac377c7b85888193b49ac187e927636cc40bc)), closes [#10907](https://github.com/vuejs/core/issues/10907) -* **compiler-core:** allow unicode to appear in simple identifiers ([#6765](https://github.com/vuejs/core/issues/6765)) ([3ea9644](https://github.com/vuejs/core/commit/3ea964473d3ac0ba3e7b0b2c22d71f23d0f69123)), closes [#6367](https://github.com/vuejs/core/issues/6367) -* **compiler-core:** change v-for key type to match Object.keys ([#10963](https://github.com/vuejs/core/issues/10963)) ([9fead52](https://github.com/vuejs/core/commit/9fead5234320848f8be82275c6b5dd0a290f2cca)), closes [#8819](https://github.com/vuejs/core/issues/8819) -* **compiler-core:** emit TS-compatible function declaration when requested ([#9363](https://github.com/vuejs/core/issues/9363)) ([5d25850](https://github.com/vuejs/core/commit/5d258502a0faffc8a451b8701f13a31b2566d068)) -* **compiler-core:** fix :key shorthand on v-for ([#10942](https://github.com/vuejs/core/issues/10942)) ([29425df](https://github.com/vuejs/core/commit/29425df1acb9e520c6ae894d06bcff73fde90edd)), closes [#10882](https://github.com/vuejs/core/issues/10882) [#10939](https://github.com/vuejs/core/issues/10939) -* **compiler-core:** make `ForIteratorExpression`'s `returns` property optional ([#11011](https://github.com/vuejs/core/issues/11011)) ([5b8c1af](https://github.com/vuejs/core/commit/5b8c1afb74e39045fcb53a011420d26e3f67eab4)) -* **compiler-core:** should set `` tag as block to retain MathML namespace after patching ([#10891](https://github.com/vuejs/core/issues/10891)) ([87c5443](https://github.com/vuejs/core/commit/87c54430448005294c41803f07f517fef848f917)) -* **compiler-core:** v-for expression missing source with spaces should emit error ([#5821](https://github.com/vuejs/core/issues/5821)) ([b9ca202](https://github.com/vuejs/core/commit/b9ca202f477be595477e182972ee9bae3f2b9f74)), closes [#5819](https://github.com/vuejs/core/issues/5819) -* **compiler-sfc:** improve type resolving for the keyof operator ([#10921](https://github.com/vuejs/core/issues/10921)) ([293cf4e](https://github.com/vuejs/core/commit/293cf4e131b6d4606e1de2cd7ea87814e2544952)), closes [#10920](https://github.com/vuejs/core/issues/10920) [#11002](https://github.com/vuejs/core/issues/11002) -* **compiler-sfc:** support as keyword with template literal types ([#11100](https://github.com/vuejs/core/issues/11100)) ([2594b1d](https://github.com/vuejs/core/commit/2594b1df57f672ac6621ac2880645e975fea581c)), closes [#10962](https://github.com/vuejs/core/issues/10962) -* **compiler-sfc:** support type resolve for keyof for intersection & union types ([#11132](https://github.com/vuejs/core/issues/11132)) ([495263a](https://github.com/vuejs/core/commit/495263a9cb356861e58a4364f2570608265486b5)), closes [#11129](https://github.com/vuejs/core/issues/11129) -* **compiler-sfc:** throw error when import macro as alias ([#11041](https://github.com/vuejs/core/issues/11041)) ([34a97ed](https://github.com/vuejs/core/commit/34a97edd2c8273c213599c44770accdb0846da8e)) -* correct the type of `
`'s `onToggle` event handler ([#10938](https://github.com/vuejs/core/issues/10938)) ([fd18ce7](https://github.com/vuejs/core/commit/fd18ce70b1a260a2485c9cd7faa30193da4b79f5)), closes [#10928](https://github.com/vuejs/core/issues/10928) -* **custom-element:** disconnect MutationObserver in nextTick in case that custom elements are moved ([#10613](https://github.com/vuejs/core/issues/10613)) ([bbb5be2](https://github.com/vuejs/core/commit/bbb5be299b500a00e60c757118c846c3b5ddd8e0)), closes [#10610](https://github.com/vuejs/core/issues/10610) -* **custom-elements:** compatibility of createElement in older versions of Chrome ([#9615](https://github.com/vuejs/core/issues/9615)) ([a88295d](https://github.com/vuejs/core/commit/a88295dc076ee867939d8b0ee2225e63c5ffb0ca)), closes [#9614](https://github.com/vuejs/core/issues/9614) -* **hmr:** avoid infinite recursion when reloading hmr components ([#6936](https://github.com/vuejs/core/issues/6936)) ([36bd9b0](https://github.com/vuejs/core/commit/36bd9b0a1fb83e61731fb80d66e265dccbedcfa8)), closes [#6930](https://github.com/vuejs/core/issues/6930) -* **hydration:** log hydration error even when using async components ([#9403](https://github.com/vuejs/core/issues/9403)) ([5afc76c](https://github.com/vuejs/core/commit/5afc76c229f9ad30eef07f34c7b65e8fe427e637)), closes [#9369](https://github.com/vuejs/core/issues/9369) -* **KeepAlive:** properly cache nested Suspense subtree ([#10912](https://github.com/vuejs/core/issues/10912)) ([07764fe](https://github.com/vuejs/core/commit/07764fe330692fadf0fc9fb9e92cb5b111df33be)) -* **npm:** explicitly add `@vue/reactivity` as dependency of `@vue/runtime-dom` ([#10468](https://github.com/vuejs/core/issues/10468)) ([ec424f6](https://github.com/vuejs/core/commit/ec424f6cd96b7e6ba74fc244c484c00fa5590aac)) -* **reactivity:** pass oldValue in debug info when triggering refs ([#8210](https://github.com/vuejs/core/issues/8210)) ([3b0a56a](https://github.com/vuejs/core/commit/3b0a56a9c4d162ec3bd725a4f2dfd776b045e727)), closes [vuejs/pinia#2061](https://github.com/vuejs/pinia/issues/2061) -* **runtime-core:** avoid traversing static children for vnodes w/ PatchFlags.BAIL ([#11115](https://github.com/vuejs/core/issues/11115)) ([b557d3f](https://github.com/vuejs/core/commit/b557d3fb8ae1e4e926c4ad0fbb2fa7abe50fd661)), closes [#10547](https://github.com/vuejs/core/issues/10547) -* **runtime-core:** do not fire mount/activated hooks if unmounted before mounted ([#9370](https://github.com/vuejs/core/issues/9370)) ([aa156ed](https://github.com/vuejs/core/commit/aa156ed5c4dc0d33ff37e201a7e89d5e0e29160e)), closes [#8898](https://github.com/vuejs/core/issues/8898) [#9264](https://github.com/vuejs/core/issues/9264) [#9617](https://github.com/vuejs/core/issues/9617) -* **runtime-core:** ensure suspense creates dep component's render effect with correct optimized flag ([#7689](https://github.com/vuejs/core/issues/7689)) ([c521f95](https://github.com/vuejs/core/commit/c521f956e1697cda36a7f1b913599e5e2004f7ba)), closes [#7688](https://github.com/vuejs/core/issues/7688) -* **runtime-core:** fix missed updates when passing text vnode to `` ([#8304](https://github.com/vuejs/core/issues/8304)) ([b310ec3](https://github.com/vuejs/core/commit/b310ec389d9738247e5b0f01711186216eb49955)), closes [#8298](https://github.com/vuejs/core/issues/8298) -* **runtime-core:** fix stale v-memo after v-if toggle ([#6606](https://github.com/vuejs/core/issues/6606)) ([edf2638](https://github.com/vuejs/core/commit/edf263847eddc910f4d2de68287d84b8c66c3860)), closes [#6593](https://github.com/vuejs/core/issues/6593) -* **runtime-core:** fix Transition for components with root-level v-if ([#7678](https://github.com/vuejs/core/issues/7678)) ([ef2e737](https://github.com/vuejs/core/commit/ef2e737577de42ea38771403f8a4dee8c892daa5)), closes [#7649](https://github.com/vuejs/core/issues/7649) -* **runtime-dom:** also set attribute for form element state ([537a571](https://github.com/vuejs/core/commit/537a571f8cf09dfe0a020e9e8891ecdd351fc3e4)), closes [#6007](https://github.com/vuejs/core/issues/6007) [#6012](https://github.com/vuejs/core/issues/6012) -* **runtime-dom:** support Symbol for input value bindings ([#10608](https://github.com/vuejs/core/issues/10608)) ([188f3ae](https://github.com/vuejs/core/commit/188f3ae533fd340603068a516a8fecc5d57426c5)), closes [#10597](https://github.com/vuejs/core/issues/10597) -* **shared:** ensure invokeArrayFns handles undefined arguments ([#10869](https://github.com/vuejs/core/issues/10869)) ([9b40d0f](https://github.com/vuejs/core/commit/9b40d0f25da868a83b0d6bf99dbbdb3ca68bb700)), closes [#10863](https://github.com/vuejs/core/issues/10863) -* **ssr:** directive binding.instance should respect exposed during ssr ([df686ab](https://github.com/vuejs/core/commit/df686abb4f0ac9d898e4fd93751e860f8cbbdbea)), closes [#7499](https://github.com/vuejs/core/issues/7499) [#7502](https://github.com/vuejs/core/issues/7502) -* **ssr:** fix hydration for node with empty text node ([#7216](https://github.com/vuejs/core/issues/7216)) ([d1011c0](https://github.com/vuejs/core/commit/d1011c07a957d858cb37725b13bc8e4d7a395490)) -* **ssr:** fix the bug that multi slot scope id does not work on component ([#6100](https://github.com/vuejs/core/issues/6100)) ([4c74302](https://github.com/vuejs/core/commit/4c74302aae64c118752db7fc2a2c229a11ebaead)), closes [#6093](https://github.com/vuejs/core/issues/6093) -* **teleport:** do not throw target warning when teleport is disabled ([#9818](https://github.com/vuejs/core/issues/9818)) ([15ee43f](https://github.com/vuejs/core/commit/15ee43f66ad2485ac212b02b444345d867b3c060)) -* **transition:** ensure Transition enterHooks are updated after clone ([#11066](https://github.com/vuejs/core/issues/11066)) ([671cf29](https://github.com/vuejs/core/commit/671cf297a550d15b19fa3fecce1b30e26cad8154)), closes [#11061](https://github.com/vuejs/core/issues/11061) -* **types/apiWatch:** correct type inference for reactive array ([#11036](https://github.com/vuejs/core/issues/11036)) ([aae2d78](https://github.com/vuejs/core/commit/aae2d78875daa476280a45e71c2f38292964efae)), closes [#9416](https://github.com/vuejs/core/issues/9416) -* **types:** improve `app.provide` type checking ([#10603](https://github.com/vuejs/core/issues/10603)) ([612bbf0](https://github.com/vuejs/core/commit/612bbf0507cbe39d701acc5dff11824802078063)), closes [#10602](https://github.com/vuejs/core/issues/10602) -* **types:** support generic argument in setup context expose method ([#8507](https://github.com/vuejs/core/issues/8507)) ([635a59b](https://github.com/vuejs/core/commit/635a59b96fe6be445525c6595ca27da7ef7c1feb)) -* **v-model:** fix the lazy modifier is not reset by other modifications ([#8547](https://github.com/vuejs/core/issues/8547)) ([a52a02f](https://github.com/vuejs/core/commit/a52a02f43fdf73d8aaad99c9cafed07f12ee422a)), closes [#8546](https://github.com/vuejs/core/issues/8546) [#6564](https://github.com/vuejs/core/issues/6564) [#6773](https://github.com/vuejs/core/issues/6773) -* **watch:** support traversing symbol properties in deep watcher ([#10969](https://github.com/vuejs/core/issues/10969)) ([a3e8aaf](https://github.com/vuejs/core/commit/a3e8aafbcc82003a66caded61143eb64c4ef02cd)), closes [#402](https://github.com/vuejs/core/issues/402) - - - -## [3.4.27](https://github.com/vuejs/core/compare/v3.4.26...v3.4.27) (2024-05-06) - - -### Bug Fixes - -* **compat:** include legacy scoped slots ([#10868](https://github.com/vuejs/core/issues/10868)) ([8366126](https://github.com/vuejs/core/commit/83661264a4ced3cb2ff6800904a86dd9e82bbfe2)), closes [#8869](https://github.com/vuejs/core/issues/8869) -* **compiler-core:** add support for arrow aysnc function with unbracketed ([#5789](https://github.com/vuejs/core/issues/5789)) ([ca7d421](https://github.com/vuejs/core/commit/ca7d421e8775f6813f8943d32ab485e0c542f98b)), closes [#5788](https://github.com/vuejs/core/issues/5788) -* **compiler-dom:** restrict createStaticVNode usage with option elements ([#10846](https://github.com/vuejs/core/issues/10846)) ([0e3d617](https://github.com/vuejs/core/commit/0e3d6178b02d0386d779720ae2cc4eac1d1ec990)), closes [#6568](https://github.com/vuejs/core/issues/6568) [#7434](https://github.com/vuejs/core/issues/7434) -* **compiler-sfc:** handle keyof operator ([#10874](https://github.com/vuejs/core/issues/10874)) ([10d34a5](https://github.com/vuejs/core/commit/10d34a5624775f20437ccad074a97270ef74c3fb)), closes [#10871](https://github.com/vuejs/core/issues/10871) -* **hydration:** handle edge case of style mismatch without style attribute ([f2c1412](https://github.com/vuejs/core/commit/f2c1412e46a8fad3e13403bfa78335c4f704f21c)), closes [#10786](https://github.com/vuejs/core/issues/10786) - - - -## [3.4.26](https://github.com/vuejs/core/compare/v3.4.25...v3.4.26) (2024-04-29) - - -### Bug Fixes - -* **compiler-core:** fix bail constant for globals ([fefce06](https://github.com/vuejs/core/commit/fefce06b41e3b75de3d748dc6399628ec5056e78)) -* **compiler-core:** remove unnecessary constant bail check ([09b4df8](https://github.com/vuejs/core/commit/09b4df809e59ef5f4bc91acfc56dc8f82a8e243a)), closes [#10807](https://github.com/vuejs/core/issues/10807) -* **runtime-core:** attrs should be readonly in functional components ([#10767](https://github.com/vuejs/core/issues/10767)) ([e8fd644](https://github.com/vuejs/core/commit/e8fd6446d14a6899e5e8ab1ee394d90088e01844)) -* **runtime-core:** ensure slot compiler marker writable ([#10825](https://github.com/vuejs/core/issues/10825)) ([9c2de62](https://github.com/vuejs/core/commit/9c2de6244cd44bc5fbfd82b5850c710ce725044f)), closes [#10818](https://github.com/vuejs/core/issues/10818) -* **runtime-core:** properly handle inherit transition during clone VNode ([#10809](https://github.com/vuejs/core/issues/10809)) ([638a79f](https://github.com/vuejs/core/commit/638a79f64a7e184f2a2c65e21d764703f4bda561)), closes [#3716](https://github.com/vuejs/core/issues/3716) [#10497](https://github.com/vuejs/core/issues/10497) [#4091](https://github.com/vuejs/core/issues/4091) -* **Transition:** re-fix [#10620](https://github.com/vuejs/core/issues/10620) ([#10832](https://github.com/vuejs/core/issues/10832)) ([accf839](https://github.com/vuejs/core/commit/accf8396ae1c9dd49759ba0546483f1d2c70c9bc)), closes [#10632](https://github.com/vuejs/core/issues/10632) [#10827](https://github.com/vuejs/core/issues/10827) - - - -## [3.4.25](https://github.com/vuejs/core/compare/v3.4.24...v3.4.25) (2024-04-24) - - -### Bug Fixes - -* **defineModel:** align prod mode runtime type generation with defineProps ([4253a57](https://github.com/vuejs/core/commit/4253a57f1703a7f1ac701d77e0a235689203461d)), closes [#10769](https://github.com/vuejs/core/issues/10769) -* **runtime-core:** properly get keepAlive child ([#10772](https://github.com/vuejs/core/issues/10772)) ([3724693](https://github.com/vuejs/core/commit/3724693a25c3f2dd13d70a8a1af760b03a4fb783)), closes [#10771](https://github.com/vuejs/core/issues/10771) -* **runtime-core:** use normal object as internal prototype for attrs and slots ([064e82f](https://github.com/vuejs/core/commit/064e82f5855f30fe0b77fe9b5e4dd22700fd634d)), closes [/github.com/vuejs/core/commit/6df53d85a207986128159d88565e6e7045db2add#r141304923](https://github.com//github.com/vuejs/core/commit/6df53d85a207986128159d88565e6e7045db2add/issues/r141304923) - - - -## [3.4.24](https://github.com/vuejs/core/compare/v3.4.23...v3.4.24) (2024-04-22) - - -### Bug Fixes - -* **compiler-core:** handle template ref bound via v-bind object on v-for ([#10706](https://github.com/vuejs/core/issues/10706)) ([da7adef](https://github.com/vuejs/core/commit/da7adefa844265eecc9c336abfc727bc05b4f16e)), closes [#10696](https://github.com/vuejs/core/issues/10696) -* **compiler-core:** properly parse await expressions in edge cases ([b92c25f](https://github.com/vuejs/core/commit/b92c25f53dff0fc1687f57ca4033d0ac25218940)), closes [#10754](https://github.com/vuejs/core/issues/10754) -* **compiler-sfc:** handle readonly operator and ReadonlyArray/Map/Set types ([5cef52a](https://github.com/vuejs/core/commit/5cef52a5c23ba8ba3239e6def03b8ff008d3cc72)), closes [#10726](https://github.com/vuejs/core/issues/10726) -* **compiler-ssr:** fix hydration mismatch for conditional slot in transition ([f12c81e](https://github.com/vuejs/core/commit/f12c81efca3fcf9a7ce478af2261ad6ab9b0bfd7)), closes [#10743](https://github.com/vuejs/core/issues/10743) -* **compiler-ssr:** fix v-html SSR for nullish values ([1ff4076](https://github.com/vuejs/core/commit/1ff407676f9495883b459779a9b0370d7588b51f)), closes [#10725](https://github.com/vuejs/core/issues/10725) -* **deps:** update compiler ([#10760](https://github.com/vuejs/core/issues/10760)) ([15df5c1](https://github.com/vuejs/core/commit/15df5c1b261b9b471eb811fd47ab7b3cfc41cf83)) -* **runtime-core:** fix edge case of KeepAlive inside Transition with slot children ([#10719](https://github.com/vuejs/core/issues/10719)) ([e51ca61](https://github.com/vuejs/core/commit/e51ca61ca060b2772e967d169548fc2f58fce6d1)), closes [#10708](https://github.com/vuejs/core/issues/10708) -* **runtime-core:** further fix slots _ctx check ([cde7f05](https://github.com/vuejs/core/commit/cde7f05787d16dbb93d9419ef5331adf992816fd)), closes [#10724](https://github.com/vuejs/core/issues/10724) -* **runtime-core:** props should be readonly via direct template access ([b93f264](https://github.com/vuejs/core/commit/b93f26464785de227b88c51a88328ae80e80d804)), closes [#8216](https://github.com/vuejs/core/issues/8216) [#10736](https://github.com/vuejs/core/issues/10736) -* **transition:** transition is breaking/flickering when enter is canceled ([#10688](https://github.com/vuejs/core/issues/10688)) ([65109a7](https://github.com/vuejs/core/commit/65109a70f187473edae8cf4df11af3c33345e6f6)) - - - -## [3.4.23](https://github.com/vuejs/core/compare/v3.4.22...v3.4.23) (2024-04-16) - - -### Bug Fixes - -* **runtime-core:** fix regression for $attrs tracking in slots ([6930e60](https://github.com/vuejs/core/commit/6930e60787e4905a50417190263ae7dd46cf5409)), closes [#10710](https://github.com/vuejs/core/issues/10710) -* **runtime-core:** use same internal object mechanism for slots ([6df53d8](https://github.com/vuejs/core/commit/6df53d85a207986128159d88565e6e7045db2add)), closes [#10709](https://github.com/vuejs/core/issues/10709) - - - -## [3.4.22](https://github.com/vuejs/core/compare/v3.4.21...v3.4.22) (2024-04-15) - - -### Bug Fixes - -* **compat:** fix $options mutation + adjust private API initialization ([d58d133](https://github.com/vuejs/core/commit/d58d133b1cde5085cc5ab0012d544cafd62a6ee6)), closes [#10626](https://github.com/vuejs/core/issues/10626) [#10636](https://github.com/vuejs/core/issues/10636) -* **compile-sfc:** analyze v-bind shorthand usage in template ([#10518](https://github.com/vuejs/core/issues/10518)) ([e5919d4](https://github.com/vuejs/core/commit/e5919d4658cfe0bb18c76611dd3c3432c57f94ab)), closes [#10515](https://github.com/vuejs/core/issues/10515) -* **compiler-core:** fix loc.source for end tags with whitespace before > ([16174da](https://github.com/vuejs/core/commit/16174da21d6c8ac0aae027dd964fc35e221ded0a)), closes [#10694](https://github.com/vuejs/core/issues/10694) [#10695](https://github.com/vuejs/core/issues/10695) -* **compiler-core:** fix v-bind shorthand for component :is ([04af950](https://github.com/vuejs/core/commit/04af9504a720c8e6de26c04b1282cf14fa1bcee3)), closes [#10469](https://github.com/vuejs/core/issues/10469) [#10471](https://github.com/vuejs/core/issues/10471) -* **compiler-sfc:** :is() and :where() in compound selectors ([#10522](https://github.com/vuejs/core/issues/10522)) ([660cadc](https://github.com/vuejs/core/commit/660cadc7aadb909ef33a6055c4374902a82607a4)), closes [#10511](https://github.com/vuejs/core/issues/10511) -* **compiler-sfc:** also search for `.tsx` when type import's extension is omitted ([#10637](https://github.com/vuejs/core/issues/10637)) ([34106bc](https://github.com/vuejs/core/commit/34106bc9c715247211273bb9c64712f04bd4879d)), closes [#10635](https://github.com/vuejs/core/issues/10635) -* **compiler-sfc:** fix defineModel coercion for boolean + string union types ([#9603](https://github.com/vuejs/core/issues/9603)) ([0cef65c](https://github.com/vuejs/core/commit/0cef65cee411356e721bbc90d731fc52fc8fce94)), closes [#9587](https://github.com/vuejs/core/issues/9587) [#10676](https://github.com/vuejs/core/issues/10676) -* **compiler-sfc:** fix universal selector scope ([#10551](https://github.com/vuejs/core/issues/10551)) ([54a6afa](https://github.com/vuejs/core/commit/54a6afa75a546078e901ce0882da53b97420fe94)), closes [#10548](https://github.com/vuejs/core/issues/10548) -* **compiler-sfc:** use options module name if options provide runtimeModuleName options ([#10457](https://github.com/vuejs/core/issues/10457)) ([e76d743](https://github.com/vuejs/core/commit/e76d7430aa7470342f3fe263145a0fa92f5898ca)), closes [#10454](https://github.com/vuejs/core/issues/10454) -* **custom-element:** avoid setting attr to null if it is removed ([#9012](https://github.com/vuejs/core/issues/9012)) ([b49306a](https://github.com/vuejs/core/commit/b49306adff4572d90a42ccd231387f16eb966bbe)), closes [#9006](https://github.com/vuejs/core/issues/9006) [#10324](https://github.com/vuejs/core/issues/10324) -* **hydration:** properly handle optimized mode during hydrate node ([#10638](https://github.com/vuejs/core/issues/10638)) ([2ec06fd](https://github.com/vuejs/core/commit/2ec06fd6c8383e11cdf4efcab1707f973bd6a54c)), closes [#10607](https://github.com/vuejs/core/issues/10607) -* **reactivity:** computed should not be detected as true by isProxy ([#10401](https://github.com/vuejs/core/issues/10401)) ([9da34d7](https://github.com/vuejs/core/commit/9da34d7af81607fddd1f32f21b3b4002402ff1cc)) -* **reactivity:** fix hasOwnProperty key coercion edge cases ([969c5fb](https://github.com/vuejs/core/commit/969c5fb30f4c725757c7385abfc74772514eae4b)) -* **reactivity:** fix tracking when hasOwnProperty is called with non-string value ([c3c5dc9](https://github.com/vuejs/core/commit/c3c5dc93fbccc196771458f0b43cd5b7ad1863f4)), closes [#10455](https://github.com/vuejs/core/issues/10455) [#10464](https://github.com/vuejs/core/issues/10464) -* **runtime-core:** fix errorHandler causes an infinite loop during execution ([#9575](https://github.com/vuejs/core/issues/9575)) ([ab59bed](https://github.com/vuejs/core/commit/ab59bedae4e5e40b28804d88a51305b236d4a873)) -* **runtime-core:** handle invalid values in callWithAsyncErrorHandling ([53d15d3](https://github.com/vuejs/core/commit/53d15d3f76184eed67a18d35e43d9a2062f8e121)) -* **runtime-core:** show hydration mismatch details for non-rectified mismatches too when __PROD_HYDRATION_MISMATCH_DETAILS__ is set ([#10599](https://github.com/vuejs/core/issues/10599)) ([0dea7f9](https://github.com/vuejs/core/commit/0dea7f9a260d93eb6c39aabac8c94c2c9b2042dd)) -* **runtime-dom:** `v-model` string/number coercion for multiselect options ([#10576](https://github.com/vuejs/core/issues/10576)) ([db374e5](https://github.com/vuejs/core/commit/db374e54c9f5e07324728b85c74eca84e28dd352)) -* **runtime-dom:** fix css v-bind for suspensed components ([#8523](https://github.com/vuejs/core/issues/8523)) ([67722ba](https://github.com/vuejs/core/commit/67722ba23b7c36ab8f3fa2d2b4df08e4ddc322e1)), closes [#8520](https://github.com/vuejs/core/issues/8520) -* **runtime-dom:** force update v-model number with leading 0 ([#10506](https://github.com/vuejs/core/issues/10506)) ([15ffe8f](https://github.com/vuejs/core/commit/15ffe8f2c954359770c57e4d9e589b0b622e4a60)), closes [#10503](https://github.com/vuejs/core/issues/10503) [#10615](https://github.com/vuejs/core/issues/10615) -* **runtime-dom:** sanitize wrongly passed string value as event handler ([#8953](https://github.com/vuejs/core/issues/8953)) ([7ccd453](https://github.com/vuejs/core/commit/7ccd453dd004076cad49ec9f56cd5fe97b7b6ed8)), closes [#8818](https://github.com/vuejs/core/issues/8818) -* **ssr:** don't render v-if comments in TransitionGroup ([#6732](https://github.com/vuejs/core/issues/6732)) ([5a96267](https://github.com/vuejs/core/commit/5a9626708e970c6fc0b6f786e3c80c22273d126f)), closes [#6715](https://github.com/vuejs/core/issues/6715) -* **Transition:** ensure the KeepAlive children unmount w/ out-in mode ([#10632](https://github.com/vuejs/core/issues/10632)) ([fc99e4d](https://github.com/vuejs/core/commit/fc99e4d3f01b190ef9fd3c218a668ba9124a32bc)), closes [#10620](https://github.com/vuejs/core/issues/10620) -* **TransitionGroup:** avoid set transition hooks for comment nodes and text nodes ([#9421](https://github.com/vuejs/core/issues/9421)) ([140a768](https://github.com/vuejs/core/commit/140a7681cc3bba22f55d97fd85a5eafe97a1230f)), closes [#4621](https://github.com/vuejs/core/issues/4621) [#4622](https://github.com/vuejs/core/issues/4622) [#5153](https://github.com/vuejs/core/issues/5153) [#5168](https://github.com/vuejs/core/issues/5168) [#7898](https://github.com/vuejs/core/issues/7898) [#9067](https://github.com/vuejs/core/issues/9067) -* **types:** avoid merging object union types when using withDefaults ([#10596](https://github.com/vuejs/core/issues/10596)) ([37ba93c](https://github.com/vuejs/core/commit/37ba93c213a81f99a68a99ef5d4065d61b150ba3)), closes [#10594](https://github.com/vuejs/core/issues/10594) - - -### Performance Improvements - -* add `__NO_SIDE_EFFECTS__` comments ([#9053](https://github.com/vuejs/core/issues/9053)) ([d46df6b](https://github.com/vuejs/core/commit/d46df6bdb14b0509eb2134b3f85297a306821c61)) -* optimize component props/slots internal object checks ([6af733d](https://github.com/vuejs/core/commit/6af733d68eb400a3d2c5ef5f465fff32b72a324e)) -* **ssr:** avoid calling markRaw on component instance proxy ([4bc9f39](https://github.com/vuejs/core/commit/4bc9f39f028af7313e5cf24c16915a1985d27bf8)) -* **ssr:** optimize setup context creation for ssr in v8 ([ca84316](https://github.com/vuejs/core/commit/ca84316bfb3410efe21333670a6ad5cd21857396)) - - - -## [3.4.21](https://github.com/vuejs/core/compare/v3.4.20...v3.4.21) (2024-02-28) - - -### Bug Fixes - -* **runtime-dom:** avoid unset option's value ([#10416](https://github.com/vuejs/core/issues/10416)) ([b3f8b5a](https://github.com/vuejs/core/commit/b3f8b5a4e700d4c47a146b6040882287d180f6cb)), closes [#10412](https://github.com/vuejs/core/issues/10412) [#10396](https://github.com/vuejs/core/issues/10396) -* **suspense:** ensure nested suspense patching if in fallback state ([#10417](https://github.com/vuejs/core/issues/10417)) ([7c97778](https://github.com/vuejs/core/commit/7c97778aec1e3513035e5df265e1b8a7801f6106)), closes [#10415](https://github.com/vuejs/core/issues/10415) -* **warning:** stringify args in warn handler ([#10414](https://github.com/vuejs/core/issues/10414)) ([bc37258](https://github.com/vuejs/core/commit/bc37258caa2f6f67f4554ab8587aca3798d92124)), closes [#10409](https://github.com/vuejs/core/issues/10409) - - - -## [3.4.20](https://github.com/vuejs/core/compare/v3.4.19...v3.4.20) (2024-02-26) - - -### Bug Fixes - -* **parser:** should not treat uppercase components as special tags ([e0e0253](https://github.com/vuejs/core/commit/e0e02535cdea1aeb1cfaff0d61d4b2555e555c36)), closes [#10395](https://github.com/vuejs/core/issues/10395) -* **runtime-dom:** avoid always resetting nullish option value ([ff130c4](https://github.com/vuejs/core/commit/ff130c470204086edaa093fb8fdc1247c69cba69)), closes [#10396](https://github.com/vuejs/core/issues/10396) -* **runtime-dom:** fix nested v-show priority regression ([364f890](https://github.com/vuejs/core/commit/364f8902c8657faec7c3a4d70a5b2c856567e92d)), closes [#10338](https://github.com/vuejs/core/issues/10338) -* **runtime-dom:** v-bind style should clear previous css string value ([#10373](https://github.com/vuejs/core/issues/10373)) ([e2d3235](https://github.com/vuejs/core/commit/e2d323538e71d404e729148fd19a08bbc2e3da9b)), closes [#10352](https://github.com/vuejs/core/issues/10352) -* **suspense:** handle suspense switching with nested suspense ([#10184](https://github.com/vuejs/core/issues/10184)) ([0f3da05](https://github.com/vuejs/core/commit/0f3da05ea201761529bb95594df1e2cee20b7107)), closes [#10098](https://github.com/vuejs/core/issues/10098) -* **types:** better typing for direct setup signature of defineComponent ([#10357](https://github.com/vuejs/core/issues/10357)) ([eadce5b](https://github.com/vuejs/core/commit/eadce5b75356656fd2209ebdb406d34823c961b7)), closes [#8604](https://github.com/vuejs/core/issues/8604) [#8855](https://github.com/vuejs/core/issues/8855) - - - -## [3.4.19](https://github.com/vuejs/core/compare/v3.4.18...v3.4.19) (2024-02-13) - - -### Bug Fixes - -* **deps:** pin lru-cache to avoid hashing error ([b8be990](https://github.com/vuejs/core/commit/b8be99018ceae92d1732dfb414df12b36b90b31f)), closes [#10300](https://github.com/vuejs/core/issues/10300) -* **hydration:** fix css vars hydration mismatch false positive on non-root nodes ([995d2fd](https://github.com/vuejs/core/commit/995d2fdcca485c24849c99f498c1edc163722e04)), closes [#10317](https://github.com/vuejs/core/issues/10317) [#10325](https://github.com/vuejs/core/issues/10325) -* **runtime-dom:** should not trigger transition when v-show value is falsy ([#10311](https://github.com/vuejs/core/issues/10311)) ([e509639](https://github.com/vuejs/core/commit/e50963903d93a7f24003b6e2c03647fdf7454b1e)) - - -### Features - -> Note: this warning is categorized as a feature but released in a patch because it does not affect public APIs. - -* **dx:** warn users when computed is self-triggering ([#10299](https://github.com/vuejs/core/issues/10299)) ([f7ba97f](https://github.com/vuejs/core/commit/f7ba97f9754a9882c1f6b1c07ca1a4040479dd13)) - - -### Performance Improvements - -* **runtime:** improve `getType()` GC and speed ([#10327](https://github.com/vuejs/core/issues/10327)) ([603a1e1](https://github.com/vuejs/core/commit/603a1e1f5ad587c077f0d974c1bbe856be22ebe9)) - - - -## [3.4.18](https://github.com/vuejs/core/compare/v3.4.17...v3.4.18) (2024-02-09) - - -### Bug Fixes - -* **dx:** warn against reserved keys as prop name ([77a804b](https://github.com/vuejs/core/commit/77a804b1d0d6a3f12fb3674cdceb85ebd6481e02)), closes [#10281](https://github.com/vuejs/core/issues/10281) -* **runtime-dom:** ensure v-show respects display value set via v-bind ([#10297](https://github.com/vuejs/core/issues/10297)) ([c224897](https://github.com/vuejs/core/commit/c224897dd4e189a10ec601a97fe08cb638ebee19)), closes [#10151](https://github.com/vuejs/core/issues/10151) - - - -## [3.4.17](https://github.com/vuejs/core/compare/v3.4.16...v3.4.17) (2024-02-09) - - -### Reverts - -* fix(runtime-dom): ensure v-show respects display value set via v-bind ([#10161](https://github.com/vuejs/core/issues/10161)) ([2cd5b05](https://github.com/vuejs/core/commit/2cd5b05c3bf171be5c0b473c084c01704a058ffa)), closes [#10294](https://github.com/vuejs/core/issues/10294) [#10151](https://github.com/vuejs/core/issues/10151) - - - -## [3.4.16](https://github.com/vuejs/core/compare/v3.4.15...v3.4.16) (2024-02-08) - - -### Bug Fixes - -* **compiler-core:** handle same-name shorthand edge case for in-DOM templates ([cb87b62](https://github.com/vuejs/core/commit/cb87b6213d7b003fa7280712c285c7c9d9f291ca)), closes [#10280](https://github.com/vuejs/core/issues/10280) -* **compiler-core:** support v-bind shorthand syntax for dynamic slot name ([#10218](https://github.com/vuejs/core/issues/10218)) ([91f058a](https://github.com/vuejs/core/commit/91f058a90cd603492649633d153b120977c4df6b)), closes [#10213](https://github.com/vuejs/core/issues/10213) -* **deps:** update compiler ([#10269](https://github.com/vuejs/core/issues/10269)) ([336bb65](https://github.com/vuejs/core/commit/336bb65820243006efdf990e6ea3610696467508)) -* **hydration:** fix SFC style v-bind hydration mismatch warnings ([#10250](https://github.com/vuejs/core/issues/10250)) ([f0b5f7e](https://github.com/vuejs/core/commit/f0b5f7ed8ddf74f9f5ba47cb65e8300370875291)), closes [#10215](https://github.com/vuejs/core/issues/10215) -* **reactivity:** avoid infinite recursion from side effects in computed getter ([#10232](https://github.com/vuejs/core/issues/10232)) ([0bced13](https://github.com/vuejs/core/commit/0bced13ee5c53a02d5f10e5db76fe38b6e131440)), closes [#10214](https://github.com/vuejs/core/issues/10214) -* **reactivity:** handle `MaybeDirty` recurse ([#10187](https://github.com/vuejs/core/issues/10187)) ([6c7e0bd](https://github.com/vuejs/core/commit/6c7e0bd88f021b0b6365370e97b0c7e243d7d70b)), closes [#10185](https://github.com/vuejs/core/issues/10185) -* **reactivity:** skip non-extensible objects when using `markRaw` ([#10289](https://github.com/vuejs/core/issues/10289)) ([2312184](https://github.com/vuejs/core/commit/2312184bc335e0d32aa4c0c0b49190b6334849b4)), closes [#10288](https://github.com/vuejs/core/issues/10288) -* **runtime-core:** avoid inlining isShallow ([#10238](https://github.com/vuejs/core/issues/10238)) ([53eee72](https://github.com/vuejs/core/commit/53eee72c3a96420db35236b5e8e4d9308a56e1b4)) -* **runtime-core:** support for nested calls to runWithContext ([#10261](https://github.com/vuejs/core/issues/10261)) ([75e02b5](https://github.com/vuejs/core/commit/75e02b5099a08166bdf407127916734c48209ee9)), closes [#10260](https://github.com/vuejs/core/issues/10260) -* **runtime-dom:** ensure v-show respects display value set via v-bind ([#10161](https://github.com/vuejs/core/issues/10161)) ([9b19f09](https://github.com/vuejs/core/commit/9b19f0912104bfccb10c8cf5beab02b21a648935)), closes [#10151](https://github.com/vuejs/core/issues/10151) -* **runtime-dom:** fix option selected update failed ([#10200](https://github.com/vuejs/core/issues/10200)) ([f31d782](https://github.com/vuejs/core/commit/f31d782e4668050a188ac0f11ba8d5b861b913ca)), closes [#10194](https://github.com/vuejs/core/issues/10194) [#10267](https://github.com/vuejs/core/issues/10267) - - -### Reverts - -* perf(templateRef): avoid double render when using template ref on v-for ([eb1b911](https://github.com/vuejs/core/commit/eb1b9116d7cd4a5747e8dadcdc5ba921df011f64)), closes [#9908](https://github.com/vuejs/core/issues/9908) [#10210](https://github.com/vuejs/core/issues/10210) [#10234](https://github.com/vuejs/core/issues/10234) - - - -## [3.4.15](https://github.com/vuejs/core/compare/v3.4.14...v3.4.15) (2024-01-18) - - -### Bug Fixes - -* **compiler-sfc:** fix type resolution for symlinked node_modules structure w/ pnpm ([75e866b](https://github.com/vuejs/core/commit/75e866bd4ef368b4e037a4933dbaf188920dc683)), closes [#10121](https://github.com/vuejs/core/issues/10121) -* correct url for production error reference links ([c3087ff](https://github.com/vuejs/core/commit/c3087ff2cce7d96c60a870f8233441311ab4dfb4)) -* **hydration:** fix incorect mismatch warning for option with non-string value and inner text ([d16a213](https://github.com/vuejs/core/commit/d16a2138a33b106b9e1499bbb9e1c67790370c97)) -* **reactivity:** re-fix [#10114](https://github.com/vuejs/core/issues/10114) ([#10123](https://github.com/vuejs/core/issues/10123)) ([c2b274a](https://github.com/vuejs/core/commit/c2b274a887f61deb7e0185d1bef3b77d31e991cc)) -* **runtime-core:** should not warn out-of-render slot fn usage when mounting another app in setup ([#10125](https://github.com/vuejs/core/issues/10125)) ([6fa33e6](https://github.com/vuejs/core/commit/6fa33e67ec42af140a86fbdb86939032c3a1f345)), closes [#10124](https://github.com/vuejs/core/issues/10124) - - -### Performance Improvements - -* **templateRef:** avoid double render when using template ref on v-for ([de4d2e2](https://github.com/vuejs/core/commit/de4d2e2143ea8397cebeb1c7a57a60007b283c9f)), closes [#9908](https://github.com/vuejs/core/issues/9908) -* **v-model:** optimize v-model multiple select w/ large lists ([2ffb956](https://github.com/vuejs/core/commit/2ffb956efe692da059f4895669084c5278871351)), closes [#10014](https://github.com/vuejs/core/issues/10014) - - - -## [3.4.14](https://github.com/vuejs/core/compare/v3.4.13...v3.4.14) (2024-01-15) - - -### Bug Fixes - -* **compiler-sfc:** enable prefixIdentifiers by default when reparsing on consumed AST ([#10105](https://github.com/vuejs/core/issues/10105)) ([48bf8e4](https://github.com/vuejs/core/commit/48bf8e4c708ec620e4852d71c8713394457108ee)) -* **deps:** update dependency postcss to ^8.4.33 ([#10110](https://github.com/vuejs/core/issues/10110)) ([a557006](https://github.com/vuejs/core/commit/a557006f8e7f110c6f322de38931dceaab8e9cbb)) -* **reactivity:** fix regression for computed with mutation ([#10119](https://github.com/vuejs/core/issues/10119)) ([20f62af](https://github.com/vuejs/core/commit/20f62afaafd422e42b99dde9c16f9a4ebfb9c5f7)), closes [#10114](https://github.com/vuejs/core/issues/10114) - - - -## [3.4.13](https://github.com/vuejs/core/compare/v3.4.12...v3.4.13) (2024-01-13) - - -### Bug Fixes - -* **reactivity:** fix dirtyLevel checks for recursive effects ([#10101](https://github.com/vuejs/core/issues/10101)) ([e45a8d2](https://github.com/vuejs/core/commit/e45a8d24b46c174deb46ed952bdaf54c81ad5a85)), closes [#10082](https://github.com/vuejs/core/issues/10082) - - - -## [3.4.12](https://github.com/vuejs/core/compare/v3.4.11...v3.4.12) (2024-01-13) - - -### Reverts - -* fix(reactivity): correct dirty assign in render function ([#10091](https://github.com/vuejs/core/issues/10091)) ([8b18481](https://github.com/vuejs/core/commit/8b1848173b0bc8fd84ce1da1af8d373c044bf073)), closes [#10098](https://github.com/vuejs/core/issues/10098) [#10100](https://github.com/vuejs/core/issues/10100) - - -## [3.4.11](https://github.com/vuejs/core/compare/v3.4.10...v3.4.11) (2024-01-12) - - -### Bug Fixes - -* **hydration:** improve mismatch when client value is null or undefined ([#10086](https://github.com/vuejs/core/issues/10086)) ([08b60f5](https://github.com/vuejs/core/commit/08b60f5d0d5b57fcf3347ef66cbeab472c475a88)) -* **reactivity:** correct dirty assign in render function ([#10091](https://github.com/vuejs/core/issues/10091)) ([8d04205](https://github.com/vuejs/core/commit/8d042050411fdf04d9d1d6c153287164b12e0255)), closes [#10082](https://github.com/vuejs/core/issues/10082) -* **runtime-core:** filter single root for nested DEV_ROOT_FRAGMENT ([#8593](https://github.com/vuejs/core/issues/8593)) ([d35b877](https://github.com/vuejs/core/commit/d35b87725ab3e2bdc86fb5781ab34939f7ec1029)), closes [#5203](https://github.com/vuejs/core/issues/5203) [#8581](https://github.com/vuejs/core/issues/8581) [#10087](https://github.com/vuejs/core/issues/10087) - - - -## [3.4.10](https://github.com/vuejs/core/compare/v3.4.9...v3.4.10) (2024-01-11) - - -### Bug Fixes - -* **hydration:** should not warn on falsy bindings of non-property keys ([3907c87](https://github.com/vuejs/core/commit/3907c87ce23cc6ef4a739b5a66ddb553e8723114)) - - - -## [3.4.9](https://github.com/vuejs/core/compare/v3.4.8...v3.4.9) (2024-01-11) - - -### Bug Fixes - -* **build:** avoid accessing __FEATURE_PROD_DEVTOOLS__ flag in root scope ([dfd9654](https://github.com/vuejs/core/commit/dfd9654665890d1bc7129f6e3c2faaa5b1f28f72)) -* **hydration:** do not warn against bindings w/ object values ([dcc68ef](https://github.com/vuejs/core/commit/dcc68ef7d48973abd8dd3178b46e50e3b0785ea4)) -* **runtime-dom:** unify behavior for v-show + style display binding ([#10075](https://github.com/vuejs/core/issues/10075)) ([cd419ae](https://github.com/vuejs/core/commit/cd419aec3cb615eaea8b2324356f38f4c0ff1fcc)), closes [#10074](https://github.com/vuejs/core/issues/10074) -* **suspense:** avoid double-patching nested suspense when parent suspense is not resolved ([#10055](https://github.com/vuejs/core/issues/10055)) ([bcda96b](https://github.com/vuejs/core/commit/bcda96b525801eb7a1d397300fb3f2f9b827ddfb)), closes [#8678](https://github.com/vuejs/core/issues/8678) - - - -## [3.4.8](https://github.com/vuejs/core/compare/v3.4.7...v3.4.8) (2024-01-10) - - -### Bug Fixes - -* **hydration:** fix class and style hydration mismatch message ([5af3987](https://github.com/vuejs/core/commit/5af398729168481c3bee741b4f36fa4f375e0f4a)), closes [#10067](https://github.com/vuejs/core/issues/10067) -* **hydration:** improve attr hydration mismatch check for boolean attrs ([972face](https://github.com/vuejs/core/commit/972facee0d892a1b6d9d4ad1da5da9306ed45c3f)), closes [#10057](https://github.com/vuejs/core/issues/10057) [#10060](https://github.com/vuejs/core/issues/10060) -* **suspense:** fix more suspense patch before resolve edge cases ([70ad4ca](https://github.com/vuejs/core/commit/70ad4caad7d19938f8ccf1ede3228a81254dd4bf)), closes [#10017](https://github.com/vuejs/core/issues/10017) - - - -## [3.4.7](https://github.com/vuejs/core/compare/v3.4.6...v3.4.7) (2024-01-09) - - -### Bug Fixes - -* **parser:** skip compat mode check for SFC root `
`, + }, + }, + }) + + expectType(parent.components!.child) + expectType(parent.components!.child2) + + // global components + expectType>( + new parent.components!.KeepAlive().$props, + ) + expectType>(new child.components!.KeepAlive().$props) + + // runtime-dom components + expectType>( + new parent.components!.Transition().$props, + ) + expectType>( + new child.components!.Transition().$props, + ) +}) + +describe('directive typing', () => { + const customDirective: Directive = { + created(_) {}, + } + + const comp = defineComponent({ + props: { + a: String, + }, + directives: { + customDirective, + localDirective: { + created(_, { arg }) { + expectType(arg) + }, + }, + }, + }) + + expectType(comp.directives!.customDirective) + expectType(comp.directives!.localDirective) + + // global directive + expectType(comp.directives!.vShow) +}) + +describe('expose typing', () => { + const Comp = defineComponent({ + expose: ['a', 'b'], + props: { + some: String, + }, + data() { + return { a: 1, b: '2', c: 1 } + }, + }) + + expectType>(Comp.expose!) + + const vm = new Comp() + // internal should still be exposed + vm.$props + + expectType(vm.a) + expectType(vm.b) + + // @ts-expect-error shouldn't be exposed + vm.c +}) + import type { AllowedComponentProps, ComponentCustomProps, + ComponentInstance, ComponentOptionsMixin, DefineComponent, + Directive, EmitsOptions, ExtractPropTypes, + KeepAliveProps, + TransitionProps, VNodeProps, + vShow, } from 'vue' // code generated by tsc / vue-tsc, make sure this continues to work @@ -1533,3 +1658,392 @@ declare const MyButton: DefineComponent< {} > ; + +describe('__typeProps backdoor for union type for conditional props', () => { + interface CommonProps { + size?: 'xl' | 'l' | 'm' | 's' | 'xs' + } + + type ConditionalProps = + | { + color?: 'normal' | 'primary' | 'secondary' + appearance?: 'normal' | 'outline' | 'text' + } + | { + color: 'white' + appearance: 'outline' + } + + type Props = CommonProps & ConditionalProps + + const Comp = defineComponent({ + __typeProps: {} as Props, + }) + // @ts-expect-error + ; + // @ts-expect-error + ; + ; + + const c = new Comp() + + // @ts-expect-error + c.$props = { color: 'white' } + // @ts-expect-error + c.$props = { color: 'white', appearance: 'text' } + c.$props = { color: 'white', appearance: 'outline' } +}) + +describe('__typeEmits backdoor, 3.3+ object syntax', () => { + type Emits = { + change: [id: number] + update: [value: string] + } + + const Comp = defineComponent({ + __typeEmits: {} as Emits, + mounted() { + this.$props.onChange?.(123) + // @ts-expect-error + this.$props.onChange?.('123') + this.$props.onUpdate?.('foo') + // @ts-expect-error + this.$props.onUpdate?.(123) + + // @ts-expect-error + this.$emit('foo') + + this.$emit('change', 123) + // @ts-expect-error + this.$emit('change', '123') + + this.$emit('update', 'test') + // @ts-expect-error + this.$emit('update', 123) + }, + }) + + ; id.toFixed(2)} /> + ; id.toUpperCase()} /> + // @ts-expect-error + ; id.slice(1)} /> + // @ts-expect-error + ; id.toFixed(2)} /> + + const c = new Comp() + // @ts-expect-error + c.$emit('foo') + + c.$emit('change', 123) + // @ts-expect-error + c.$emit('change', '123') + + c.$emit('update', 'test') + // @ts-expect-error + c.$emit('update', 123) +}) + +describe('__typeEmits backdoor, call signature syntax', () => { + type Emits = { + (e: 'change', id: number): void + (e: 'update', value: string): void + } + + const Comp = defineComponent({ + __typeEmits: {} as Emits, + mounted() { + this.$props.onChange?.(123) + // @ts-expect-error + this.$props.onChange?.('123') + this.$props.onUpdate?.('foo') + // @ts-expect-error + this.$props.onUpdate?.(123) + + // @ts-expect-error + this.$emit('foo') + + this.$emit('change', 123) + // @ts-expect-error + this.$emit('change', '123') + + this.$emit('update', 'test') + // @ts-expect-error + this.$emit('update', 123) + }, + }) + + ; id.toFixed(2)} /> + ; id.toUpperCase()} /> + // @ts-expect-error + ; id.slice(1)} /> + // @ts-expect-error + ; id.toFixed(2)} /> + + const c = new Comp() + // @ts-expect-error + c.$emit('foo') + + c.$emit('change', 123) + // @ts-expect-error + c.$emit('change', '123') + + c.$emit('update', 'test') + // @ts-expect-error + c.$emit('update', 123) +}) + +describe('__typeRefs backdoor, object syntax', () => { + type Refs = { + foo: number + } + + const Parent = defineComponent({ + __typeRefs: {} as { child: ComponentInstance }, + }) + const Child = defineComponent({ + __typeRefs: {} as Refs, + }) + const c = new Parent() + const refs = c.$refs + + expectType>(refs.child) + expectType(refs.child.$refs.foo) +}) + +defineComponent({ + props: { + foo: [String, null], + }, + setup(props) { + expectType>(false) + expectType(props.foo) + }, +}) + +import type * as vue from 'vue' + +interface ErrorMessageSlotProps { + message: string | undefined +} +/** + * #10842 + * component types generated by vue-tsc + * relying on legacy CreateComponentPublicInstance signature + */ +declare const ErrorMessage: { + new (...args: any[]): vue.CreateComponentPublicInstance< + Readonly< + vue.ExtractPropTypes<{ + as: { + type: StringConstructor + default: any + } + name: { + type: StringConstructor + required: true + } + }> + >, + () => + | VNode< + vue.RendererNode, + vue.RendererElement, + { + [key: string]: any + } + > + | vue.Slot + | VNode< + vue.RendererNode, + vue.RendererElement, + { + [key: string]: any + } + >[] + | { + default: () => VNode< + vue.RendererNode, + vue.RendererElement, + { + [key: string]: any + } + >[] + }, + unknown, + {}, + {}, + vue.ComponentOptionsMixin, + vue.ComponentOptionsMixin, + {}, + vue.VNodeProps & + vue.AllowedComponentProps & + vue.ComponentCustomProps & + Readonly< + vue.ExtractPropTypes<{ + as: { + type: StringConstructor + default: any + } + name: { + type: StringConstructor + required: true + } + }> + >, + { + as: string + }, + true, + {}, + {}, + { + P: {} + B: {} + D: {} + C: {} + M: {} + Defaults: {} + }, + Readonly< + vue.ExtractPropTypes<{ + as: { + type: StringConstructor + default: any + } + name: { + type: StringConstructor + required: true + } + }> + >, + () => + | VNode< + vue.RendererNode, + vue.RendererElement, + { + [key: string]: any + } + > + | vue.Slot + | VNode< + vue.RendererNode, + vue.RendererElement, + { + [key: string]: any + } + >[] + | { + default: () => VNode< + vue.RendererNode, + vue.RendererElement, + { + [key: string]: any + } + >[] + }, + {}, + {}, + {}, + { + as: string + } + > + __isFragment?: never + __isTeleport?: never + __isSuspense?: never +} & vue.ComponentOptionsBase< + Readonly< + vue.ExtractPropTypes<{ + as: { + type: StringConstructor + default: any + } + name: { + type: StringConstructor + required: true + } + }> + >, + () => + | VNode< + vue.RendererNode, + vue.RendererElement, + { + [key: string]: any + } + > + | vue.Slot + | VNode< + vue.RendererNode, + vue.RendererElement, + { + [key: string]: any + } + >[] + | { + default: () => VNode< + vue.RendererNode, + vue.RendererElement, + { + [key: string]: any + } + >[] + }, + unknown, + {}, + {}, + vue.ComponentOptionsMixin, + vue.ComponentOptionsMixin, + {}, + string, + { + as: string + }, + {}, + string, + {} +> & + vue.VNodeProps & + vue.AllowedComponentProps & + vue.ComponentCustomProps & + (new () => { + $slots: { + default: (arg: ErrorMessageSlotProps) => VNode[] + } + }) +; + +// #10843 +createApp({}).component( + 'SomeComponent', + defineComponent({ + props: { + title: String, + }, + setup(props) { + expectType(props.title) + return {} + }, + }), +) + +const Comp = defineComponent({ + props: { + actionText: { + type: {} as PropType, + default: 'Become a sponsor', + }, + }, + __typeProps: {} as { + actionText?: string + }, +}) + +const instance = new Comp() +function expectString(s: string) {} +// instance prop with default should be non-null +expectString(instance.actionText) + +// public prop on $props should be optional +// @ts-expect-error +expectString(instance.$props.actionText) diff --git a/packages/dts-test/defineCustomElement.test-d.ts b/packages-private/dts-test/defineCustomElement.test-d.ts similarity index 55% rename from packages/dts-test/defineCustomElement.test-d.ts rename to packages-private/dts-test/defineCustomElement.test-d.ts index 2d48dbc1bc9..f81f8b8fa61 100644 --- a/packages/dts-test/defineCustomElement.test-d.ts +++ b/packages-private/dts-test/defineCustomElement.test-d.ts @@ -68,7 +68,7 @@ describe('inject', () => { }) describe('defineCustomElement using defineComponent return type', () => { - test('with emits', () => { + test('with object emits', () => { const Comp1Vue = defineComponent({ props: { a: String, @@ -80,6 +80,56 @@ describe('defineCustomElement using defineComponent return type', () => { const Comp = defineCustomElement(Comp1Vue) expectType(Comp) - expectType(new Comp().a) + const instance = new Comp() + expectType(instance.a) + instance.a = '' + }) + + test('with array emits', () => { + const Comp1Vue = defineComponent({ + props: { + a: Number, + }, + emits: ['click'], + }) + const Comp = defineCustomElement(Comp1Vue) + expectType(Comp) + + const instance = new Comp() + expectType(instance.a) + instance.a = 42 + }) + + test('with required props', () => { + const Comp1Vue = defineComponent({ + props: { + a: { type: Number, required: true }, + }, + }) + const Comp = defineCustomElement(Comp1Vue) + expectType(Comp) + + const instance = new Comp() + expectType(instance.a) + instance.a = 42 + }) + + test('with default props', () => { + const Comp1Vue = defineComponent({ + props: { + a: { + type: Number, + default: 1, + validator: () => true, + }, + }, + emits: ['click'], + }) + const Comp = defineCustomElement(Comp1Vue) + expectType(Comp) + + const instance = new Comp() + expectType(instance.a) + instance.a = 42 }) }) diff --git a/packages-private/dts-test/directives.test-d.ts b/packages-private/dts-test/directives.test-d.ts new file mode 100644 index 00000000000..5b87ebf71e5 --- /dev/null +++ b/packages-private/dts-test/directives.test-d.ts @@ -0,0 +1,58 @@ +import { type Directive, type ObjectDirective, vModelText } from 'vue' +import { describe, expectType } from './utils' + +type ExtractBinding = T extends ( + el: any, + binding: infer B, + vnode: any, + prev: any, +) => any + ? B + : never + +declare function testDirective< + Value, + Modifiers extends string = string, + Arg extends string = string, +>(): ExtractBinding> + +describe('vmodel', () => { + expectType>( + vModelText, + ) + // @ts-expect-error + expectType>(vModelText) +}) + +describe('custom', () => { + expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + }>(testDirective()) + + expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + // @ts-expect-error + }>(testDirective()) + + expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + // @ts-expect-error + }>(testDirective()) + + expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + // @ts-expect-error + }>(testDirective()) +}) diff --git a/packages/dts-test/extractProps.test-d.ts b/packages-private/dts-test/extractProps.test-d.ts similarity index 100% rename from packages/dts-test/extractProps.test-d.ts rename to packages-private/dts-test/extractProps.test-d.ts diff --git a/packages/dts-test/functionalComponent.test-d.tsx b/packages-private/dts-test/functionalComponent.test-d.tsx similarity index 100% rename from packages/dts-test/functionalComponent.test-d.tsx rename to packages-private/dts-test/functionalComponent.test-d.tsx diff --git a/packages/dts-test/h.test-d.ts b/packages-private/dts-test/h.test-d.ts similarity index 100% rename from packages/dts-test/h.test-d.ts rename to packages-private/dts-test/h.test-d.ts diff --git a/packages/dts-test/inject.test-d.ts b/packages-private/dts-test/inject.test-d.ts similarity index 92% rename from packages/dts-test/inject.test-d.ts rename to packages-private/dts-test/inject.test-d.ts index 2e8341ff0ae..e545ef623d0 100644 --- a/packages/dts-test/inject.test-d.ts +++ b/packages-private/dts-test/inject.test-d.ts @@ -2,6 +2,7 @@ import { type InjectionKey, type Ref, createApp, + defineComponent, inject, provide, ref, @@ -52,3 +53,9 @@ provide(123, { size: 'foo' }) const app = createApp({}) // @ts-expect-error app.provide(injectionKeyRef, ref({})) + +defineComponent({ + provide: { + [injectionKeyRef]: { size: 'foo' }, + }, +}) diff --git a/packages/dts-test/package.json b/packages-private/dts-test/package.json similarity index 74% rename from packages/dts-test/package.json rename to packages-private/dts-test/package.json index a6ea96bfa86..72b1b6ea630 100644 --- a/packages/dts-test/package.json +++ b/packages-private/dts-test/package.json @@ -4,6 +4,6 @@ "version": "0.0.0", "dependencies": { "vue": "workspace:*", - "@vue/dts-built-test": "workspace:*" + "dts-built-test": "workspace:*" } } diff --git a/packages/dts-test/reactivity.test-d.ts b/packages-private/dts-test/reactivity.test-d.ts similarity index 100% rename from packages/dts-test/reactivity.test-d.ts rename to packages-private/dts-test/reactivity.test-d.ts diff --git a/packages/dts-test/ref.test-d.ts b/packages-private/dts-test/ref.test-d.ts similarity index 88% rename from packages/dts-test/ref.test-d.ts rename to packages-private/dts-test/ref.test-d.ts index 46d39214b93..929e3d1a1ab 100644 --- a/packages/dts-test/ref.test-d.ts +++ b/packages-private/dts-test/ref.test-d.ts @@ -5,6 +5,7 @@ import { type Ref, type ShallowRef, type ToRefs, + type WritableComputedRef, computed, isRef, proxyRefs, @@ -17,6 +18,7 @@ import { toRefs, toValue, unref, + useTemplateRef, } from 'vue' import { type IsAny, type IsUnion, describe, expectType } from './utils' @@ -180,6 +182,39 @@ describe('allow getter and setter types to be unrelated', () => { const d = {} as T const e = ref(d) e.value = d + + const f = ref(ref(0)) + expectType(f.value) + // @ts-expect-error + f.value = ref(1) +}) + +// computed +describe('allow computed getter and setter types to be unrelated', () => { + const obj = ref({ + name: 'foo', + }) + + const c = computed({ + get() { + return JSON.stringify(obj.value) + }, + set(val: typeof obj.value) { + obj.value = val + }, + }) + + c.value = { name: 'bar' } // object + + expectType(c.value) +}) + +describe('Type safety for `WritableComputedRef` and `ComputedRef`', () => { + // @ts-expect-error + const writableComputed: WritableComputedRef = computed(() => '') + // should allow + const immutableComputed: ComputedRef = writableComputed + expectType>(immutableComputed) }) // shallowRef @@ -464,5 +499,25 @@ describe('toRef <-> toValue', () => { }) // unref -declare const text: ShallowRef | ComputedRef | MaybeRef -expectType(unref(text)) +// #8747 +declare const unref1: number | Ref | ComputedRef +expectType(unref(unref1)) + +// #11356 +declare const unref2: + | MaybeRef + | ShallowRef + | ComputedRef + | WritableComputedRef +expectType(unref(unref2)) + +// toValue +expectType(toValue(unref1)) +expectType(toValue(unref2)) + +// useTemplateRef +const tRef = useTemplateRef('foo') +expectType>>(tRef) + +const tRef2 = useTemplateRef('bar') +expectType>>(tRef2) diff --git a/packages/dts-test/setupHelpers.test-d.ts b/packages-private/dts-test/setupHelpers.test-d.ts similarity index 88% rename from packages/dts-test/setupHelpers.test-d.ts rename to packages-private/dts-test/setupHelpers.test-d.ts index 883ebe6b254..64c944e0be2 100644 --- a/packages/dts-test/setupHelpers.test-d.ts +++ b/packages-private/dts-test/setupHelpers.test-d.ts @@ -5,6 +5,7 @@ import { defineComponent, defineEmits, defineModel, + defineOptions, defineProps, defineSlots, toRefs, @@ -42,7 +43,8 @@ describe('defineProps w/ generics', () => { test() }) -describe('defineProps w/ type declaration + withDefaults', () => { +describe('defineProps w/ type declaration + withDefaults', () => { const res = withDefaults( defineProps<{ number?: number @@ -55,6 +57,7 @@ describe('defineProps w/ type declaration + withDefaults', () => { z?: string bool?: boolean boolAndUndefined: boolean | undefined + foo?: T }>(), { number: 123, @@ -64,6 +67,7 @@ describe('defineProps w/ type declaration + withDefaults', () => { genStr: () => '', y: undefined, z: 'string', + foo: '' as any, }, ) @@ -80,6 +84,7 @@ describe('defineProps w/ type declaration + withDefaults', () => { expectType(res.x) expectType(res.y) expectType(res.z) + expectType(res.foo) expectType(res.bool) expectType(res.boolAndUndefined) @@ -137,6 +142,31 @@ describe('defineProps w/ object union + withDefaults', () => { >(props) }) +describe('defineProps w/ generic discriminate union + withDefaults', () => { + interface B { + b?: string + } + interface S extends B { + mode: 'single' + v: T + } + interface M extends B { + mode: 'multiple' + v: T[] + } + type Props = S | M + const props = withDefaults(defineProps(), { + b: 'b', + }) + + if (props.mode === 'single') { + expectType(props.v) + } + if (props.mode === 'multiple') { + expectType(props.v) + } +}) + describe('defineProps w/ generic type declaration + withDefaults', { expectType(res2.bool) }) +describe('withDefaults w/ defineProp type is different from the defaults type', () => { + const res1 = withDefaults( + defineProps<{ + bool?: boolean + }>(), + { bool: false, value: false }, + ) + expectType(res1.bool) + + // @ts-expect-error + res1.value +}) + describe('defineProps w/ runtime declaration', () => { // runtime declaration const props = defineProps({ @@ -501,3 +544,21 @@ describe('toRefs w/ type declaration', () => { }>() expectType>(toRefs(props).file) }) + +describe('defineOptions', () => { + defineOptions({ + name: 'MyComponent', + inheritAttrs: true, + }) + + defineOptions({ + // @ts-expect-error props should be defined via defineProps() + props: ['props'], + // @ts-expect-error emits should be defined via defineEmits() + emits: ['emits'], + // @ts-expect-error slots should be defined via defineSlots() + slots: { default: 'default' }, + // @ts-expect-error expose should be defined via defineExpose() + expose: ['expose'], + }) +}) diff --git a/packages/dts-test/tsconfig.test.json b/packages-private/dts-test/tsconfig.test.json similarity index 100% rename from packages/dts-test/tsconfig.test.json rename to packages-private/dts-test/tsconfig.test.json diff --git a/packages/dts-test/tsx.test-d.tsx b/packages-private/dts-test/tsx.test-d.tsx similarity index 100% rename from packages/dts-test/tsx.test-d.tsx rename to packages-private/dts-test/tsx.test-d.tsx diff --git a/packages/dts-test/utils.d.ts b/packages-private/dts-test/utils.d.ts similarity index 100% rename from packages/dts-test/utils.d.ts rename to packages-private/dts-test/utils.d.ts diff --git a/packages/dts-test/watch.test-d.ts b/packages-private/dts-test/watch.test-d.ts similarity index 100% rename from packages/dts-test/watch.test-d.ts rename to packages-private/dts-test/watch.test-d.ts diff --git a/packages/sfc-playground/README.md b/packages-private/sfc-playground/README.md similarity index 100% rename from packages/sfc-playground/README.md rename to packages-private/sfc-playground/README.md diff --git a/packages/sfc-playground/index.html b/packages-private/sfc-playground/index.html similarity index 63% rename from packages/sfc-playground/index.html rename to packages-private/sfc-playground/index.html index 2319a918767..3a21d956cd6 100644 --- a/packages/sfc-playground/index.html +++ b/packages-private/sfc-playground/index.html @@ -1,4 +1,4 @@ - + @@ -7,13 +7,16 @@ Vue SFC Playground diff --git a/packages/sfc-playground/package.json b/packages-private/sfc-playground/package.json similarity index 90% rename from packages/sfc-playground/package.json rename to packages-private/sfc-playground/package.json index 74302db32e0..b43247e9cb9 100644 --- a/packages/sfc-playground/package.json +++ b/packages-private/sfc-playground/package.json @@ -9,7 +9,7 @@ "serve": "vite preview" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.1.1", + "@vitejs/plugin-vue": "catalog:", "vite": "catalog:" }, "dependencies": { diff --git a/packages/sfc-playground/public/logo.svg b/packages-private/sfc-playground/public/logo.svg similarity index 100% rename from packages/sfc-playground/public/logo.svg rename to packages-private/sfc-playground/public/logo.svg diff --git a/packages/sfc-playground/src/App.vue b/packages-private/sfc-playground/src/App.vue similarity index 97% rename from packages/sfc-playground/src/App.vue rename to packages-private/sfc-playground/src/App.vue index 7501b200ce8..7cbe573f6e2 100644 --- a/packages/sfc-playground/src/App.vue +++ b/packages-private/sfc-playground/src/App.vue @@ -54,7 +54,8 @@ const sfcOptions = computed( template: { isProd: productionMode.value, compilerOptions: { - isCustomElement: (tag: string) => tag === 'mjx-container', + isCustomElement: (tag: string) => + tag === 'mjx-container' || tag.startsWith('custom-'), }, }, }), diff --git a/packages/sfc-playground/src/Header.vue b/packages-private/sfc-playground/src/Header.vue similarity index 98% rename from packages/sfc-playground/src/Header.vue rename to packages-private/sfc-playground/src/Header.vue index 8e810d89441..922a2b111ac 100644 --- a/packages/sfc-playground/src/Header.vue +++ b/packages-private/sfc-playground/src/Header.vue @@ -125,7 +125,7 @@ function toggleDark() { import { onMounted, ref } from 'vue' +import Copy from './icons/Copy.vue' const expanded = ref(false) const versions = ref() @@ -53,6 +54,12 @@ function setVersion(v: string) { expanded.value = false } +function copyVersion(v: string) { + window.navigator.clipboard.writeText(v).then(() => { + alert('Vue version has been copied to clipboard.') + }) +} + onMounted(() => { window.addEventListener('click', () => { expanded.value = false @@ -76,11 +83,19 @@ onMounted(() => {
  • loading versions...
  • v{{ ver }} +
  • @@ -120,4 +135,17 @@ onMounted(() => { .versions .active a { color: var(--green); } + +.versions .versions-item { + display: flex; + justify-content: space-between; +} + +.versions .versions-item .version-copy { + display: none; +} + +.versions .versions-item:hover .version-copy { + display: block; +} diff --git a/packages/sfc-playground/src/download/download.ts b/packages-private/sfc-playground/src/download/download.ts similarity index 100% rename from packages/sfc-playground/src/download/download.ts rename to packages-private/sfc-playground/src/download/download.ts diff --git a/packages/sfc-playground/src/download/template/README.md b/packages-private/sfc-playground/src/download/template/README.md similarity index 100% rename from packages/sfc-playground/src/download/template/README.md rename to packages-private/sfc-playground/src/download/template/README.md diff --git a/packages/sfc-playground/src/download/template/index.html b/packages-private/sfc-playground/src/download/template/index.html similarity index 95% rename from packages/sfc-playground/src/download/template/index.html rename to packages-private/sfc-playground/src/download/template/index.html index 030a6ff51bf..e631329c1b0 100644 --- a/packages/sfc-playground/src/download/template/index.html +++ b/packages-private/sfc-playground/src/download/template/index.html @@ -1,4 +1,4 @@ - + diff --git a/packages/sfc-playground/src/download/template/main.js b/packages-private/sfc-playground/src/download/template/main.js similarity index 100% rename from packages/sfc-playground/src/download/template/main.js rename to packages-private/sfc-playground/src/download/template/main.js diff --git a/packages/sfc-playground/src/download/template/package.json b/packages-private/sfc-playground/src/download/template/package.json similarity index 80% rename from packages/sfc-playground/src/download/template/package.json rename to packages-private/sfc-playground/src/download/template/package.json index 6747f24c8c0..8e989966839 100644 --- a/packages/sfc-playground/src/download/template/package.json +++ b/packages-private/sfc-playground/src/download/template/package.json @@ -11,7 +11,7 @@ "vue": "^3.4.0" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.1.1", - "vite": "^5.3.5" + "@vitejs/plugin-vue": "^5.1.2", + "vite": "^5.4.2" } } diff --git a/packages/sfc-playground/src/download/template/vite.config.js b/packages-private/sfc-playground/src/download/template/vite.config.js similarity index 100% rename from packages/sfc-playground/src/download/template/vite.config.js rename to packages-private/sfc-playground/src/download/template/vite.config.js diff --git a/packages-private/sfc-playground/src/icons/Copy.vue b/packages-private/sfc-playground/src/icons/Copy.vue new file mode 100644 index 00000000000..f3851da63cc --- /dev/null +++ b/packages-private/sfc-playground/src/icons/Copy.vue @@ -0,0 +1,14 @@ + diff --git a/packages/sfc-playground/src/icons/Download.vue b/packages-private/sfc-playground/src/icons/Download.vue similarity index 100% rename from packages/sfc-playground/src/icons/Download.vue rename to packages-private/sfc-playground/src/icons/Download.vue diff --git a/packages/sfc-playground/src/icons/GitHub.vue b/packages-private/sfc-playground/src/icons/GitHub.vue similarity index 100% rename from packages/sfc-playground/src/icons/GitHub.vue rename to packages-private/sfc-playground/src/icons/GitHub.vue diff --git a/packages/sfc-playground/src/icons/Moon.vue b/packages-private/sfc-playground/src/icons/Moon.vue similarity index 100% rename from packages/sfc-playground/src/icons/Moon.vue rename to packages-private/sfc-playground/src/icons/Moon.vue diff --git a/packages/sfc-playground/src/icons/Reload.vue b/packages-private/sfc-playground/src/icons/Reload.vue similarity index 100% rename from packages/sfc-playground/src/icons/Reload.vue rename to packages-private/sfc-playground/src/icons/Reload.vue diff --git a/packages/sfc-playground/src/icons/Share.vue b/packages-private/sfc-playground/src/icons/Share.vue similarity index 100% rename from packages/sfc-playground/src/icons/Share.vue rename to packages-private/sfc-playground/src/icons/Share.vue diff --git a/packages/sfc-playground/src/icons/Sun.vue b/packages-private/sfc-playground/src/icons/Sun.vue similarity index 100% rename from packages/sfc-playground/src/icons/Sun.vue rename to packages-private/sfc-playground/src/icons/Sun.vue diff --git a/packages/sfc-playground/src/main.ts b/packages-private/sfc-playground/src/main.ts similarity index 100% rename from packages/sfc-playground/src/main.ts rename to packages-private/sfc-playground/src/main.ts diff --git a/packages/sfc-playground/src/vue-dev-proxy-prod.ts b/packages-private/sfc-playground/src/vue-dev-proxy-prod.ts similarity index 100% rename from packages/sfc-playground/src/vue-dev-proxy-prod.ts rename to packages-private/sfc-playground/src/vue-dev-proxy-prod.ts diff --git a/packages/sfc-playground/src/vue-dev-proxy.ts b/packages-private/sfc-playground/src/vue-dev-proxy.ts similarity index 100% rename from packages/sfc-playground/src/vue-dev-proxy.ts rename to packages-private/sfc-playground/src/vue-dev-proxy.ts diff --git a/packages/sfc-playground/src/vue-server-renderer-dev-proxy.ts b/packages-private/sfc-playground/src/vue-server-renderer-dev-proxy.ts similarity index 100% rename from packages/sfc-playground/src/vue-server-renderer-dev-proxy.ts rename to packages-private/sfc-playground/src/vue-server-renderer-dev-proxy.ts diff --git a/packages/sfc-playground/vercel.json b/packages-private/sfc-playground/vercel.json similarity index 100% rename from packages/sfc-playground/vercel.json rename to packages-private/sfc-playground/vercel.json diff --git a/packages/sfc-playground/vite.config.ts b/packages-private/sfc-playground/vite.config.ts similarity index 77% rename from packages/sfc-playground/vite.config.ts rename to packages-private/sfc-playground/vite.config.ts index ee9bbd4abf4..2e77f1970a7 100644 --- a/packages/sfc-playground/vite.config.ts +++ b/packages-private/sfc-playground/vite.config.ts @@ -34,7 +34,7 @@ function copyVuePlugin(): Plugin { name: 'copy-vue', generateBundle() { const copyFile = (file: string) => { - const filePath = path.resolve(__dirname, file) + const filePath = path.resolve(__dirname, '../../packages', file) const basename = path.basename(file) if (!fs.existsSync(filePath)) { throw new Error( @@ -49,11 +49,11 @@ function copyVuePlugin(): Plugin { }) } - copyFile(`../vue/dist/vue.esm-browser.js`) - copyFile(`../vue/dist/vue.esm-browser.prod.js`) - copyFile(`../vue/dist/vue.runtime.esm-browser.js`) - copyFile(`../vue/dist/vue.runtime.esm-browser.prod.js`) - copyFile(`../server-renderer/dist/server-renderer.esm-browser.js`) + copyFile(`vue/dist/vue.esm-browser.js`) + copyFile(`vue/dist/vue.esm-browser.prod.js`) + copyFile(`vue/dist/vue.runtime.esm-browser.js`) + copyFile(`vue/dist/vue.runtime.esm-browser.prod.js`) + copyFile(`server-renderer/dist/server-renderer.esm-browser.js`) }, } } diff --git a/packages/template-explorer/README.md b/packages-private/template-explorer/README.md similarity index 100% rename from packages/template-explorer/README.md rename to packages-private/template-explorer/README.md diff --git a/packages/template-explorer/_redirects b/packages-private/template-explorer/_redirects similarity index 100% rename from packages/template-explorer/_redirects rename to packages-private/template-explorer/_redirects diff --git a/packages-private/template-explorer/index.html b/packages-private/template-explorer/index.html new file mode 100644 index 00000000000..d1db969f01b --- /dev/null +++ b/packages-private/template-explorer/index.html @@ -0,0 +1,24 @@ +Vue Template Explorer + + + + +
    +
    + + + + + diff --git a/packages-private/template-explorer/local.html b/packages-private/template-explorer/local.html new file mode 100644 index 00000000000..c86cdb6b34c --- /dev/null +++ b/packages-private/template-explorer/local.html @@ -0,0 +1,24 @@ +Vue Template Explorer + + + + +
    +
    + + + + + diff --git a/packages/template-explorer/package.json b/packages-private/template-explorer/package.json similarity index 89% rename from packages/template-explorer/package.json rename to packages-private/template-explorer/package.json index f9afd0dd42c..03260c964ab 100644 --- a/packages/template-explorer/package.json +++ b/packages-private/template-explorer/package.json @@ -11,7 +11,7 @@ "enableNonBrowserBranches": true }, "dependencies": { - "monaco-editor": "^0.50.0", + "monaco-editor": "^0.51.0", "source-map-js": "^1.2.0" } } diff --git a/packages/template-explorer/src/index.ts b/packages-private/template-explorer/src/index.ts similarity index 100% rename from packages/template-explorer/src/index.ts rename to packages-private/template-explorer/src/index.ts diff --git a/packages/template-explorer/src/options.ts b/packages-private/template-explorer/src/options.ts similarity index 100% rename from packages/template-explorer/src/options.ts rename to packages-private/template-explorer/src/options.ts diff --git a/packages/template-explorer/src/theme.ts b/packages-private/template-explorer/src/theme.ts similarity index 100% rename from packages/template-explorer/src/theme.ts rename to packages-private/template-explorer/src/theme.ts diff --git a/packages/template-explorer/style.css b/packages-private/template-explorer/style.css similarity index 100% rename from packages/template-explorer/style.css rename to packages-private/template-explorer/style.css diff --git a/packages-private/vite-debug/App.vue b/packages-private/vite-debug/App.vue new file mode 100644 index 00000000000..95b3be8eee5 --- /dev/null +++ b/packages-private/vite-debug/App.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/packages-private/vite-debug/README.md b/packages-private/vite-debug/README.md new file mode 100644 index 00000000000..4f035ae6f8d --- /dev/null +++ b/packages-private/vite-debug/README.md @@ -0,0 +1 @@ +This package is used for debugging issues that are related to `@vitejs/plugin-vue`, or can only be reproduced in a Vite-based setup. It aims to be as close to production as possible so Vue packages are resolved to the dist files instead of source. diff --git a/packages-private/vite-debug/index.html b/packages-private/vite-debug/index.html new file mode 100644 index 00000000000..79052a023ba --- /dev/null +++ b/packages-private/vite-debug/index.html @@ -0,0 +1,2 @@ + +
    diff --git a/packages-private/vite-debug/main.ts b/packages-private/vite-debug/main.ts new file mode 100644 index 00000000000..52668a0a545 --- /dev/null +++ b/packages-private/vite-debug/main.ts @@ -0,0 +1,6 @@ +import { createApp } from 'vue' +import App from './App.vue' + +const app = createApp(App) + +app.mount('#app') diff --git a/packages-private/vite-debug/package.json b/packages-private/vite-debug/package.json new file mode 100644 index 00000000000..b0f2bad2b2d --- /dev/null +++ b/packages-private/vite-debug/package.json @@ -0,0 +1,15 @@ +{ + "name": "vite-debug", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "serve": "vite preview" + }, + "devDependencies": { + "@vitejs/plugin-vue": "catalog:", + "vite": "catalog:", + "vue": "workspace:*" + } +} diff --git a/packages-private/vite-debug/tsconfig.json b/packages-private/vite-debug/tsconfig.json new file mode 100644 index 00000000000..ceecb1cde14 --- /dev/null +++ b/packages-private/vite-debug/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler" + }, + "include": ["./*"] +} diff --git a/packages-private/vite-debug/vite.config.ts b/packages-private/vite-debug/vite.config.ts new file mode 100644 index 00000000000..c40aa3c361b --- /dev/null +++ b/packages-private/vite-debug/vite.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +export default defineConfig({ + plugins: [vue()], +}) diff --git a/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap index 678548e35b5..942eed4c4dc 100644 --- a/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap +++ b/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap @@ -2,7 +2,7 @@ exports[`compiler: parse > Edge Cases > invalid html 1`] = ` { - "cached": 0, + "cached": [], "children": [ { "children": [ @@ -86,7 +86,7 @@ exports[`compiler: parse > Edge Cases > invalid html 1`] = ` exports[`compiler: parse > Edge Cases > self closing multiple tag 1`] = ` { - "cached": 0, + "cached": [], "children": [ { "children": [], @@ -280,7 +280,7 @@ exports[`compiler: parse > Edge Cases > self closing multiple tag 1`] = ` exports[`compiler: parse > Edge Cases > valid html 1`] = ` { - "cached": 0, + "cached": [], "children": [ { "children": [ @@ -498,7 +498,7 @@ exports[`compiler: parse > Edge Cases > valid html 1`] = ` exports[`compiler: parse > Errors > CDATA_IN_HTML_CONTENT > 1`] = ` { - "cached": 0, + "cached": [], "children": [ { "children": [], @@ -550,7 +550,7 @@ exports[`compiler: parse > Errors > CDATA_IN_HTML_CONTENT >