Deprecated parseExpressions option was removed
Action requiredVue 3.5 removes the previously deprecated parseExpressions compiler option.
Remove usage of the deprecated parseExpressions compiler option from custom compiler integrations.
Compare Vue.js versions and see exactly what changes, what requires action, and what you can start using.
Vue 3.5 removes the previously deprecated parseExpressions compiler option.
Remove usage of the deprecated parseExpressions compiler option from custom compiler integrations.
Vue 3.5 enables Reactive Props Destructure by default. Variables destructured from defineProps() remain reactive and can use native JavaScript default-value syntax.
<script setup lang="ts">
const props = withDefaults(
defineProps<{
count?: number
}>(),
{
count: 0
}
)
watchEffect(() => {
console.log(props.count)
})
</script><script setup lang="ts">
const {
count = 0
} = defineProps<{
count?: number
}>()
watchEffect(() => {
console.log(count)
})
</script>No migration is required. Reactive Props Destructure is enabled by default in Vue 3.5 and can be adopted incrementally.
Vue 3.5 introduces useTemplateRef(), providing a cleaner Composition API for accessing template refs without manually declaring matching ref variables.
<script setup>
import {
ref,
onMounted
} from "vue"
const input = ref(null)
onMounted(() => {
input.value.focus()
})
</script>
<template>
<input ref="input" />
</template><script setup>
import {
useTemplateRef,
onMounted
} from "vue"
const input =
useTemplateRef("input")
onMounted(() => {
input.value?.focus()
})
</script>
<template>
<input ref="input" />
</template>No migration is required. Existing template refs remain valid. useTemplateRef() can be adopted for clearer template-ref access and improved tooling support.
Vue 3.5 introduces onWatcherCleanup(), allowing cleanup logic to be registered from inside watch and watchEffect callbacks.
import {
watch,
onWatcherCleanup
} from "vue"
watch(id, async (newId) => {
const controller =
new AbortController()
onWatcherCleanup(() => {
controller.abort()
})
await fetch(
`/api/users/${newId}`,
{
signal: controller.signal
}
)
})No migration is required. onWatcherCleanup() provides an alternative cleanup API for watchers and is particularly useful for cancelling stale asynchronous work.
Vue 3.5 extends watcher handles with pause() and resume(), allowing watcher execution to be temporarily suspended without stopping the watcher permanently.
const {
stop,
pause,
resume
} = watch(source, callback)
pause()
// watcher temporarily suspended
resume()
// watcher active again
stop()No migration is required. Existing watcher handles continue to work and can optionally use pause() and resume().
Vue 3.5 allows the deep option on watchers to be a number, limiting how many object levels Vue traverses when tracking nested changes.
watch(
state,
callback,
{
deep: true
}
)watch(
state,
callback,
{
deep: 2
}
)No migration is required. Numeric deep values can be used to reduce traversal costs when full deep observation is unnecessary.
Vue 3.5 allows async components to control when server-rendered markup is hydrated using built-in strategies such as idle, visibility, interaction and media-query hydration.
import {
defineAsyncComponent,
hydrateOnVisible
} from "vue"
const AsyncCard =
defineAsyncComponent({
loader: () =>
import("./Card.vue"),
hydrate:
hydrateOnVisible()
})No migration is required. SSR applications can adopt lazy hydration strategies for async components where immediate hydration is unnecessary.
Vue 3.5 introduces useId() for generating application-unique IDs that remain stable across server rendering and client hydration.
<script setup>
import { useId } from "vue"
const id = useId()
</script>
<template>
<label :for="id">
Name
</label>
<input :id="id" />
</template>No migration is required. useId() is useful for accessible form relationships and reusable SSR-safe components that require unique identifiers.
Vue 3.5 adds the defer prop to Teleport, allowing its target to be resolved after other parts of the same update cycle have mounted.
<Teleport to="#target">
<Modal />
</Teleport>
<!-- target generally needs
to already exist --><Teleport
defer
to="#target"
>
<Modal />
</Teleport>
<div id="target"></div>No migration is required. Use defer when the Teleport target is rendered later in the same component tree.
Vue 3.5 supports directly nesting Teleport inside Transition, simplifying transition handling for teleported content.
No migration is required. Existing Teleport and Transition usage remains valid.
Vue 3.5 introduces the data-allow-mismatch attribute for intentionally suppressing specific SSR hydration mismatch warnings.
<span
data-allow-mismatch="text"
>
{{ new Date().toLocaleString() }}
</span>No migration is required. Use data-allow-mismatch only for intentional server/client differences rather than hiding actual hydration bugs.
Vue 3.5 introduces app.onUnmount(), allowing plugins and application-level integrations to register cleanup callbacks that run when the application is unmounted.
const app = createApp(App)
app.onUnmount(() => {
cleanupExternalResources()
})
app.mount("#app")No migration is required. Plugin and integration authors can use app.onUnmount() for application-level cleanup.
Vue 3.5 improves Vue Custom Elements with APIs and behavior for host access, shadow-root configuration, CSP nonces and other integration scenarios.
No migration is required. Applications and libraries using Vue Custom Elements can adopt the expanded configuration and host APIs as needed.
Vue 3.5 adds app.config.throwUnhandledErrorInProduction for applications that want unhandled framework errors to be thrown in production instead of only being logged.
const app = createApp(App)
app.config
.throwUnhandledErrorInProduction =
trueNo migration is required. Enable this option only when production error handling and monitoring are prepared for thrown unhandled errors.
Vue 3.5 refactors the reactivity system using version counting and doubly-linked dependency tracking, improving performance and reducing memory usage without changing expected application behavior.
No migration is required. Existing applications automatically benefit after upgrading.
Vue 3.5 improves reactive array tracking, significantly reducing overhead for large reactive arrays and common array operations.
No migration is required. Applications using large reactive arrays receive the optimization automatically.