diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a176ee1c..930c8b590 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +## [3.5.12](https://github.com/vuejs/core/compare/v3.5.11...v3.5.12) (2024-10-11) + + +### Bug Fixes + +* **compiler-dom:** avoid stringify option with null value ([#12096](https://github.com/vuejs/core/issues/12096)) ([f6d9926](https://github.com/vuejs/core/commit/f6d99262364b7444ebab8742158599e8cdd79eaa)), closes [#12093](https://github.com/vuejs/core/issues/12093) +* **compiler-sfc:** do not skip TSInstantiationExpression when transforming props destructure ([#12064](https://github.com/vuejs/core/issues/12064)) ([d3ecde8](https://github.com/vuejs/core/commit/d3ecde8a696ff62c8d0ab067fd1d7ee0565b63c5)) +* **compiler-sfc:** use sass modern api if available and avoid deprecation warning ([#11992](https://github.com/vuejs/core/issues/11992)) ([4474c11](https://github.com/vuejs/core/commit/4474c113d1fb1c26298dd6794275d5b5c7cc4d93)) +* **compiler:** clone loc to `ifNode` ([#12131](https://github.com/vuejs/core/issues/12131)) ([cde2c06](https://github.com/vuejs/core/commit/cde2c0671b00d4f6111fcbd7aa76e45872f20b0c)), closes [vuejs/language-tools#4911](https://github.com/vuejs/language-tools/issues/4911) +* **custom-element:** properly remove hyphenated attribute ([#12143](https://github.com/vuejs/core/issues/12143)) ([e16e9a7](https://github.com/vuejs/core/commit/e16e9a7341e7cfb3c443da4e5e5b06e8158712c3)), closes [#12139](https://github.com/vuejs/core/issues/12139) +* **defineModel:** handle kebab-case model correctly ([#12063](https://github.com/vuejs/core/issues/12063)) ([c0418a3](https://github.com/vuejs/core/commit/c0418a3b8fa96a0b108ab71b7aab5d3388f90557)), closes [#12060](https://github.com/vuejs/core/issues/12060) +* **deps:** update dependency monaco-editor to ^0.52.0 ([#12119](https://github.com/vuejs/core/issues/12119)) ([f7cbea2](https://github.com/vuejs/core/commit/f7cbea2111c7770a180b640f36f6a5d4d6abc698)) +* **hydration:** provide compat fallback for idle callback hydration strategy ([#11935](https://github.com/vuejs/core/issues/11935)) ([1ae545a](https://github.com/vuejs/core/commit/1ae545a3786abef983be1c969726489685569c92)) +* **reactivity:** trigger reactivity for Map key `undefined` ([#12055](https://github.com/vuejs/core/issues/12055)) ([7ad289e](https://github.com/vuejs/core/commit/7ad289e1e7fea654524008ff91e43a8b8a55ef22)), closes [#12054](https://github.com/vuejs/core/issues/12054) +* **runtime-core:** allow symbol values for slot prop key ([#12069](https://github.com/vuejs/core/issues/12069)) ([d9d4d4e](https://github.com/vuejs/core/commit/d9d4d4e158cd51a9ddda249f29de8467f60b2792)), closes [#12068](https://github.com/vuejs/core/issues/12068) +* **runtime-core:** fix required prop check false positive for kebab-case edge cases ([#12034](https://github.com/vuejs/core/issues/12034)) ([9da1ac1](https://github.com/vuejs/core/commit/9da1ac156552ac449754e1373aac7e349841becb)), closes [#12011](https://github.com/vuejs/core/issues/12011) +* **runtime-dom:** prevent unnecessary updates in v-model checkbox when value is unchanged ([#12146](https://github.com/vuejs/core/issues/12146)) ([ea943af](https://github.com/vuejs/core/commit/ea943afe404c4ca4b729906c5e8daf7aa2ccde9b)), closes [#12144](https://github.com/vuejs/core/issues/12144) +* **teleport:** handle disabled teleport with updateCssVars ([#12113](https://github.com/vuejs/core/issues/12113)) ([76a8223](https://github.com/vuejs/core/commit/76a8223199c148b79a5c0ea19e235164809760cd)), closes [#12112](https://github.com/vuejs/core/issues/12112) +* **transition/ssr:** make transition appear work with Suspense in SSR ([#12047](https://github.com/vuejs/core/issues/12047)) ([f1a4f67](https://github.com/vuejs/core/commit/f1a4f67aedfe83e440c54222213f070774faa421)), closes [#12046](https://github.com/vuejs/core/issues/12046) +* **types:** ensure `this.$props` type does not include `string` ([#12123](https://github.com/vuejs/core/issues/12123)) ([704173e](https://github.com/vuejs/core/commit/704173e24276706de672cca6c9507e4dd9651197)), closes [#12122](https://github.com/vuejs/core/issues/12122) +* **types:** retain union type narrowing with defaults applied ([#12108](https://github.com/vuejs/core/issues/12108)) ([05685a9](https://github.com/vuejs/core/commit/05685a9d7c42d4cd37169b867833776b91154fed)), closes [#12106](https://github.com/vuejs/core/issues/12106) +* **useId:** ensure useId consistency when using serverPrefetch ([#12128](https://github.com/vuejs/core/issues/12128)) ([b4d3534](https://github.com/vuejs/core/commit/b4d35349d8bc39aa15bd3f1094d230e5928b177c)), closes [#12102](https://github.com/vuejs/core/issues/12102) +* **watch:** watchEffect clean-up with SSR ([#12097](https://github.com/vuejs/core/issues/12097)) ([b094c72](https://github.com/vuejs/core/commit/b094c72b3d40c52c7124f145a9db028509a11202)), closes [#11956](https://github.com/vuejs/core/issues/11956) + + +### Performance Improvements + +* **reactivity:** avoid unnecessary recursion in removeSub ([#12135](https://github.com/vuejs/core/issues/12135)) ([ec917cf](https://github.com/vuejs/core/commit/ec917cfdb9d0169cd0835d3a0e28244242657dc9)) + + + ## [3.5.11](https://github.com/vuejs/core/compare/v3.5.10...v3.5.11) (2024-10-03) diff --git a/package.json b/package.json index b58d1f73c..c2392b88a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, - "version": "3.5.11", - "packageManager": "pnpm@9.12.0", + "version": "3.5.12", + "packageManager": "pnpm@9.12.1", "type": "module", "scripts": { "dev": "node scripts/dev.js", @@ -66,9 +66,9 @@ "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-replace": "5.0.4", - "@swc/core": "^1.7.28", + "@swc/core": "^1.7.35", "@types/hash-sum": "^1.0.2", - "@types/node": "^20.16.10", + "@types/node": "^20.16.11", "@types/semver": "^7.5.8", "@types/serve-handler": "^6.1.4", "@vitest/coverage-v8": "^2.1.1", @@ -84,7 +84,7 @@ "jsdom": "^25.0.0", "lint-staged": "^15.2.10", "lodash": "^4.17.21", - "magic-string": "^0.30.11", + "magic-string": "^0.30.12", "markdown-table": "^3.0.3", "marked": "13.0.3", "npm-run-all2": "^6.2.3", @@ -105,7 +105,7 @@ "todomvc-app-css": "^2.4.3", "tslib": "^2.7.0", "typescript": "~5.6.2", - "typescript-eslint": "^8.8.0", + "typescript-eslint": "^8.8.1", "vite": "catalog:", "vitest": "^2.1.1" }, diff --git a/packages-private/dts-test/defineComponent.test-d.tsx b/packages-private/dts-test/defineComponent.test-d.tsx index 9b4c18471..fda3ca485 100644 --- a/packages-private/dts-test/defineComponent.test-d.tsx +++ b/packages-private/dts-test/defineComponent.test-d.tsx @@ -2068,3 +2068,13 @@ expectString(instance.actionText) // public prop on $props should be optional // @ts-expect-error expectString(instance.$props.actionText) + +// #12122 +defineComponent({ + props: { foo: String }, + render() { + expectType<{ readonly foo?: string }>(this.$props) + // @ts-expect-error + expectType(this.$props) + }, +}) diff --git a/packages-private/dts-test/setupHelpers.test-d.ts b/packages-private/dts-test/setupHelpers.test-d.ts index 4074176ff..7b5d6f147 100644 --- a/packages-private/dts-test/setupHelpers.test-d.ts +++ b/packages-private/dts-test/setupHelpers.test-d.ts @@ -240,6 +240,23 @@ describe('withDefaults w/ defineProp type is different from the defaults type', res1.value }) +describe('withDefaults w/ defineProp discriminate union type', () => { + const props = withDefaults( + defineProps< + { type: 'button'; buttonType?: 'submit' } | { type: 'link'; href: string } + >(), + { + type: 'button', + }, + ) + if (props.type === 'button') { + expectType<'submit' | undefined>(props.buttonType) + } + if (props.type === 'link') { + expectType(props.href) + } +}) + describe('defineProps w/ runtime declaration', () => { // runtime declaration const props = defineProps({ diff --git a/packages-private/sfc-playground/src/App.vue b/packages-private/sfc-playground/src/App.vue index c9295d41b..d163b1a3e 100644 --- a/packages-private/sfc-playground/src/App.vue +++ b/packages-private/sfc-playground/src/App.vue @@ -123,6 +123,7 @@ onMounted(() => { :prod="productionMode" :ssr="useSSRMode" :autoSave="autoSave" + :theme="theme" @toggle-theme="toggleTheme" @toggle-prod="toggleProdMode" @toggle-ssr="toggleSSR" diff --git a/packages-private/sfc-playground/src/Header.vue b/packages-private/sfc-playground/src/Header.vue index 2778724b0..aea6c022a 100644 --- a/packages-private/sfc-playground/src/Header.vue +++ b/packages-private/sfc-playground/src/Header.vue @@ -15,6 +15,7 @@ const props = defineProps<{ prod: boolean ssr: boolean autoSave: boolean + theme: 'dark' | 'light' }>() const emit = defineEmits([ 'toggle-theme', @@ -117,7 +118,11 @@ function toggleDark() { > {{ autoSave ? 'AutoSave ON' : 'AutoSave OFF' }} - diff --git a/packages/compiler-core/package.json b/packages/compiler-core/package.json index 4fb760168..a4e941aa4 100644 --- a/packages/compiler-core/package.json +++ b/packages/compiler-core/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-core", - "version": "3.5.11", + "version": "3.5.12", "description": "@vue/compiler-core", "main": "index.js", "module": "dist/compiler-core.esm-bundler.js", diff --git a/packages/compiler-core/src/parser.ts b/packages/compiler-core/src/parser.ts index 0d66d2055..95c5e129f 100644 --- a/packages/compiler-core/src/parser.ts +++ b/packages/compiler-core/src/parser.ts @@ -933,6 +933,10 @@ function getLoc(start: number, end?: number): SourceLocation { } } +export function cloneLoc(loc: SourceLocation): SourceLocation { + return getLoc(loc.start.offset, loc.end.offset) +} + function setLocEnd(loc: SourceLocation, end: number) { loc.end = tokenizer.getPos(end) loc.source = getSlice(loc.start.offset, end) diff --git a/packages/compiler-core/src/transforms/vIf.ts b/packages/compiler-core/src/transforms/vIf.ts index caefa197e..54c505407 100644 --- a/packages/compiler-core/src/transforms/vIf.ts +++ b/packages/compiler-core/src/transforms/vIf.ts @@ -30,6 +30,7 @@ import { import { ErrorCodes, createCompilerError } from '../errors' import { processExpression } from './transformExpression' import { validateBrowserExpression } from '../validateExpression' +import { cloneLoc } from '../parser' import { CREATE_COMMENT, FRAGMENT } from '../runtimeHelpers' import { findDir, findProp, getMemoedVNodeCall, injectProp } from '../utils' import { PatchFlags } from '@vue/shared' @@ -110,7 +111,7 @@ export function processIf( const branch = createIfBranch(node, dir) const ifNode: IfNode = { type: NodeTypes.IF, - loc: node.loc, + loc: cloneLoc(node.loc), branches: [branch], } context.replaceNode(ifNode) diff --git a/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap b/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap index 78b576af5..a863eb32e 100644 --- a/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap +++ b/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap @@ -32,6 +32,23 @@ return function render(_ctx, _cache) { }" `; +exports[`stringify static html > should bail for