原文
今天,很高兴地发布Vue3.5
!
此次要
版本不包含破坏更改
,只包括内部改进和有用
的新函数.这里包含一些亮点
.
反应式系统优化
在3.5
中,Vue
的响应式系统
经历了另一次重大重构
,实现了更好性能
并显著提高
了(-56%)
内存使用率
而行为不变.
此重构
还解决了在SSR
时,因挂起计算
而导致的过时计算值和内存问题
.
此外,3.5
还优化了大型深度响应式数组
的响应性跟踪
,有时会使此类操作
速度提高10
倍.
ReactiveProps
析构
在3.5
版本中稳定了响应时属性析构
.现在默认启用该功能
后,从<script setup>
中的defineProps
调用析构
的变量,现在是响应式
的.
注意,此特征通过利用js
的本地默认值语法
,大大简化了用默认值
声明属性
的过程:
//以前
const props = withDefaults(defineProps<{count?: numbermsg?: string}>(),{count: 0,msg: 'hello'}
)
现在:
const { count = 0, msg = 'hello' } = defineProps<{count?: numbermessage?: string
}>()
通过编译器会自动把访问析构变量
(如计数
)编译到props.count
中,因此在访问
时会跟踪它们.
类似props.count
,监视
析构的属性
变量或给它传递到可组合项
中并同时保留响应性
,需要在取器
中包装它:
watch(count /*...*/)
//^导致编译时错误
watch(() => count /*...*/)
//在取器中工作,
//组合应用`toValue()`来归一化输入
useDynamicCount(() => count)
对那些希望更好区分
析构属性
和普通变量
的人,@vue/languagetools2.1
提供了一个选入
设置来为它们启用内联
提示.
SSR
改进
3.5
为服务渲染(SSR)
带来了一些期待已久的改进
.
懒冻结
通过defineAsyncComponent()API
的冻结
选项指定策略
,异步组件
现在可控制何时应该冻结它们
.如,要仅在组件
可见时冻结组件
:
import { defineAsyncComponent, hydrateOnVisible } from 'vue'
const AsyncComp = defineAsyncComponent({loader: () => import('./Comp.vue'),hydrate: hydrateOnVisible()
})
核心API
有意降级
,Nuxt
团队已在此函数
上面构建了更高级的语法糖
.这里
useId()
useId()
是一个可生成每个应用
,保证在服务器和客户渲染
中保持稳定
的唯一的ID
的API
.
它们可用来生成表单元素
和助手函数属性
的ID
,且可在SSR
应用中使用
,而不会导致冻结不匹配
:
<script setup>
import { useId } from 'vue'
const id = useId()
</script>
<template><form><label :for="id">Name:</label><input :id="id" type="text" /></form>
</template>
允许不匹配数据(data-allow-mismatch)
如果客户值
不可避免地与其服务器
对应值(如日期)不同,现在可用该
属性抑制生成的冻结不匹配警告
:
<span dataallowmismatch>{{ data.toLocaleString() }}</span>
还可为属性
提供值限制允许的不匹配类型
,其中可能的值为text,children,class,style
和attribute
.
自定义元素改进
3.5
修复了许多与defineCustomElement()API
相关的长期问题
,并添加了许多使用Vue
编写自定义元素
的新能力
:
1,configureApp
选项支持自定义元素的应用配置
.
2,新增useHost(),useShadowRoot()
和this.$host
接口,来访问自定义元素
的主机元素
和阴影根
.
3,支持传递shadowRoot:false
来挂载没有ShadowDOM
的自定义元素
.
4,支持通过自定义元素
来附加
到<style>
标签上来提供nonce
选项.
5,可通过第二个参数
把这些新的仅限自定义元素的选项
传递给defineCustomElement
:
JS
import MyElement from './MyElement.ce.vue'
defineCustomElements(MyElement, {shadowRoot: false,nonce: 'xxx',configureApp(app) {app.config.errorHandler = ...}
})
其他显著功能
useTemplateRef()
3.5
引入了一个通过useTemplateRef()API
取模板引用
的新方法
:
<script setup>
import { useTemplateRef } from 'vue'
const inputRef = useTemplateRef('input')
</script>
<template><input ref="input">
</template>
在3.5
前,建议使用变量名
与静引用
属性匹配
的普通引用
.旧方法要求引用
属性可由编译器解析
,因此仅限于静态引用
属性.
相比之下,useTemplateRef()
通过运行时串ID
匹配引用
,因此支持动态引用
绑定到不断变化
的ID
.
@vue/languagetools2.1
还特殊支持新语法
,因此在使用useTemplateRef()
时,会根据模板
中是否有引用
属性收到自动补全和警告
:
懒传递
内置<Teleport>
组件的一个已知约束
是,在挂载Teleport
组件时,必须要有目标
元素.这阻止了用户在传递
后传递内容
到Vue
渲染的其他元素
.
在3.5
中,为<Teleport>
引入了一个延迟
属性,它会在当前渲染周期
后挂载它
,所以如下现在可以工作了
:
<Teleport defer target="#container">...</Teleport>
<div id="container"></div>
因为默认要后向兼容
,此行为需要延迟
属性.
onWatcherCleanup()
3.5
引入了一个全局导入
的API
,onWatcherCleanup()
,来在监视器
中注册清理回调
:
import { watch, onWatcherCleanup } from 'vue'
watch(id, (newId) => {const controller = new AbortController()fetch(`/api/${newId}`, { signal: controller.signal }).then(() => {//回调逻辑})onWatcherCleanup(() => {//(中止过时请求)controller.abort()})
})