惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
Google DeepMind News
Google DeepMind News
V
V2EX
B
Blog RSS Feed
有赞技术团队
有赞技术团队
博客园 - Franky
美团技术团队
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
腾讯CDC
云风的 BLOG
云风的 BLOG
L
LangChain Blog
GbyAI
GbyAI
The Cloudflare Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Stack Overflow Blog
Stack Overflow Blog
博客园 - 【当耐特】
The Register - Security
The Register - Security
大猫的无限游戏
大猫的无限游戏
D
Docker
Vercel News
Vercel News
Blog — PlanetScale
Blog — PlanetScale
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 司徒正美
人人都是产品经理
人人都是产品经理
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
N
Netflix TechBlog - Medium
博客园_首页
A
About on SuperTechFans
J
Java Code Geeks
量子位
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
Recent Announcements
Recent Announcements
G
Google Developers Blog
小众软件
小众软件
博客园 - 叶小钗
WordPress大学
WordPress大学
博客园 - 聂微东
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Martin Fowler
Martin Fowler
S
SegmentFault 最新的问题
F
Full Disclosure
Jina AI
Jina AI
H
Help Net Security

The Vue Point

Announcing VitePress 1.0 | The Vue Point Announcing Vue 3.4 | The Vue Point Vue 2 is Approaching End Of Life Announcing Vue 3.3 | The Vue Point Volar: a New Beginning | The Vue Point 2022 Year In Review | The Vue Point On Escape's Vue 2 to Svelte Migration Volar 1.0 "Nika" Released! | The Vue Point Vue 2.7 "Naruto" Released | The Vue Point Vue 2.7 is Now in Beta Vue 3 as the New Default Vue 3.2 Released! | The Vue Point Reflections for 2020-2021 | The Vue Point Announcing Vue 3.0 "One Piece"
Announcing Vue 3.5 | The Vue Point
2024-09-01 · via The Vue Point

Today we are excited to announce the release of Vue 3.5 "Tengen Toppa Gurren Lagann"!

This minor release contains no breaking changes and includes both internal improvements and useful new features. We will cover some highlights in this blog post - for a full list of changes and new features, please consult the full changelog on GitHub.


Reactivity System Optimizations ​

In 3.5, Vue's reactivity system has undergone another major refactor that achieves better performance and significantly improved memory usage (-56%) with no behavior changes. The refactor also resolves stale computed values and memory issues caused by hanging computeds during SSR.

In addition, 3.5 also optimizes reactivity tracking for large, deeply reactive arrays, making such operations up to 10x faster in some cases.

Details: PR#10397, PR#9511

Reactive Props Destructure ​

Reactive Props Destructure has been stabilized in 3.5. With the feature now enabled by default, variables destructured from a defineProps call in <script setup> are now reactive. Notably, this feature significantly simplifies declaring props with default values by leveraging JavaScript's native default value syntax:

Before

ts

const props = withDefaults(
  defineProps<{
    count?: number
    msg?: string
  }>(),
  {
    count: 0,
    msg: 'hello'
  }
)

After

ts

const { count = 0, msg = 'hello' } = defineProps<{
  count?: number
  message?: string
}>()

Access to a destructured variable, e.g. count, is automatically compiled into props.count by the compiler, so they are tracked on access. Similar to props.count, watching the destructured prop variable or passing it into a composable while retaining reactivity requires wrapping it in a getter:

js

watch(count /* ... */)
//    ^ results in compile-time error

watch(() => count /* ... */)
//    ^ wrap in a getter, works as expected

// composables should normalize the input with `toValue()`
useDynamicCount(() => count)

For those who prefer to better distinguish destructured props from normal variables, @vue/language-tools 2.1 has shipped an opt-in setting to enable inlay hints for them:

inlay hints for destructured props

Details:

  • See docs for usage and caveats.
  • See RFC#502 for the history and design rationale behind this feature.

SSR Improvements ​

3.5 brings a few long-requested improvements to server-side rendering (SSR).

Lazy Hydration ​

Async components can now control when they should be hydrated by specifying a strategy via the hydrate option of the defineAsyncComponent() API. For example, to only hydrate a component when it becomes visible:

js

import { defineAsyncComponent, hydrateOnVisible } from 'vue'

const AsyncComp = defineAsyncComponent({
  loader: () => import('./Comp.vue'),
  hydrate: hydrateOnVisible()
})

The core API is intentionally lower level and the Nuxt team is already building higher-level syntax sugar on top of this feature.

Details: PR#11458

useId()

useId() is an API that can be used to generate unique-per-application IDs that are guaranteed to be stable across the server and client renders. They can be used to generate IDs for form elements and accessibility attributes, and can be used in SSR applications without leading to hydration mismatches:

vue

<script setup>
import { useId } from 'vue'

const id = useId()
</script>

<template>
  <form>
    <label :for="id">Name:</label>
    <input :id="id" type="text" />
  </form>
</template>

Details: PR#11404

data-allow-mismatch

In cases where a client value will be inevitably different from its server counterpart (e.g. dates), we can now suppress the resulting hydration mismatch warnings with data-allow-mismatch attributes:

vue

<span data-allow-mismatch>{{ data.toLocaleString() }}</span>

You can also limit what types of mismatches are allowed by providing a value to the attribute, where the possible values are text, children, class, style, and attribute.

Custom Elements Improvements ​

3.5 fixes many long-standing issues related to the defineCustomElement() API, and adds a number of new capabilities for authoring custom elements with Vue:

  • Support app configurations for custom elements via the configureApp option.
  • Add useHost(), useShadowRoot(), and this.$host APIs for accessing the host element and shadow root of a custom element.
  • Support mounting custom elements without Shadow DOM by passing shadowRoot: false.
  • Support providing a nonce option, which will be attached to <style> tags injected by custom elements.

These new custom-element-only options can be passed to defineCustomElement via a second argument:

js

import MyElement from './MyElement.ce.vue'

defineCustomElements(MyElement, {
  shadowRoot: false,
  nonce: 'xxx',
  configureApp(app) {
    app.config.errorHandler = ...
  }
})

Other Notable Features ​

useTemplateRef()

3.5 introduces a new way of obtaining Template Refs via the useTemplateRef() API:

vue

<script setup>
import { useTemplateRef } from 'vue'

const inputRef = useTemplateRef('input')
</script>

<template>
  <input ref="input">
</template>

Prior to 3.5, we recommended using plain refs with variable names matching static ref attributes. The old approach required the ref attributes to be analyzable by the compiler and thus was limited to static ref attributes. In comparison, useTemplateRef() matches the refs via runtime string IDs, therefore supporting dynamic ref bindings to changing IDs.

@vue/language-tools 2.1 has also implemented special support for the new syntax, so you will get auto-completion and warnings when using useTemplateRef() based on presence of ref attributes in your template:

inlay hints for destructured props

Deferred Teleport ​

A known constraint of the built-in <Teleport> component is that its target element must exist at the time the teleport component is mounted. This prevented users from teleporting content to other elements rendered by Vue after the teleport.

In 3.5, we have introduced a defer prop for <Teleport> which mounts it after the current render cycle, so this will now work:

html

<Teleport defer target="#container">...</Teleport>
<div id="container"></div>

This behavior requires the defer prop because the default behavior needs to be backwards compatible.

Details: PR#11387

onWatcherCleanup()

3.5 introduces a globally imported API, onWatcherCleanup(), for registering cleanup callbacks in watchers:

js

import { watch, onWatcherCleanup } from 'vue'

watch(id, (newId) => {
  const controller = new AbortController()

  fetch(`/api/${newId}`, { signal: controller.signal }).then(() => {
    // callback logic
  })

  onWatcherCleanup(() => {
    // abort stale request
    controller.abort()
  })
})

For a comprehensive list of changes and features in 3.5, check out of the the full changelog on GitHub. Happy hacking!