当前位置: 首页 > article >正文

Vue3.5常用特性整理

Vue3.5 发布已近半年,抽空整理下常用的新增/改动特性

响应式 Props 解构

Vue3.5 中 Props 正式支持解构了,并添加了响应式跟踪

设置默认值

使用 JavaScript 原生的默认值语法声明 props 默认值

以前

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

现在

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

响应式解构

当在同一个 <script setup> 代码块中访问由 defineProps 解构的变量时,Vue 编译器会自动在前面添加 props

以前

 
const { foo } = defineProps(['foo'])
watchEffect(() => {
// 在 3.5 之前只运行一次
console.log(foo)
})

现在

 
const { foo } = defineProps(['foo'])
watchEffect(() => {
// 在 3.5 中在 "foo" prop 变化时重新执行
console.log(foo)
// `foo` 由编译器转换为 `props.foo`,以上等同于 `console.log(props.foo)`
})

与之类似,监听解构的 prop 变量 或 将其传递到可组合项中同时保留响应性 时需要将其包装在 getter 中

以前

 
const { foo } = defineProps(['foo'])
watch(foo, /* ... */)

现在:

 
// watch(foo, /* ... */) 等价于 watch(props.foo, ...),我们给 watch 传递的是一个值而不是响应式数据源
watch(() => foo, /* ... */)
// 传递解构的 prop 到外部函数中并保持响应性
useComposable(() => foo)

监听(watch / watcheffect) 相关

watch 支持指定深度 deep: number

watch 的 deep 选项现在支持传入数字,来指定监听的深度

 
const state = ref({
a: {
b: {
c: 1
}
}
})
watch(state, (newValue) => {
console.log(`state: ${newValue}`)
},
{ deep: 2 }
)
state.a.b = { c: 2 } // 更改了第二层的属性,触发监听
state.a.b.c = 2 // 更改了第三层的属性,不触发监听

清理函数 onWatcherCleanup / onEffectCleanup

以前我们在监听函数中要发送异步请求时,很可能发生请求参数发生变化的情况,这时我们需要设置全局变量存储 AbortController,并在组件卸载之前清理它

 
import { watch, onBeforeUnmount } from "vue"
let controller = new AbortController()
watch(state, (newValue) => {
controller.abort() // 取消上一次的请求
controller = new AbortController()
fetch(`/api/${newValue}`, { signal: controller.signal }).then(() => {
// 回调逻辑
})
});
// 组件卸载前也要清理
onBeforeUnmount(() => controller.abort())

现在有了清理函数 onWatcherCleanup / onEffectCleanup 后,我们可以直接调用它来清理之前的 调用(异步)函数/请求

 
import { watch, onWatcherCleanup } from 'vue'
watch(id, (newId) => {
const controller = new AbortController()
fetch(`/api/${newId}`, { signal: controller.signal }).then(() => {
// 回调逻辑
})
onWatcherCleanup(() => {
// 终止过期请求
controller.abort()
})
})

onEffectCleanup 函数写法类似以上,不同的是导入来源

 
import { onEffectCleanup } from "@vue/reactivity";

[!WARNING]
onWatcherCleanup 仅在 Vue 3.5+ 中支持,并且必须在 watchEffect 效果函数或 watch 回调函数的同步执行期间调用:你不能在异步函数的 await 语句之后调用它。

watch 返回值增强

watch 返回值中新增 暂停/恢复侦听器,可以更细致的控制监听作用范围

 
const { stop, pause, resume } = watch(() => {})
// 暂停侦听器
pause()
// 稍后恢复
resume()

SSR 改进

惰性激活 Lazy Hydration

异步组件可以通过 defineAsyncComponent() API 中的 hydrate 选项来控制何时进行激活

在空闲时进行激活
 
import { defineAsyncComponent, hydrateOnIdle } from 'vue'
const AsyncComp = defineAsyncComponent({
loader: () => import('./Comp.vue'),
hydrate: hydrateOnIdle(/* 传递可选的最大超时 */)
})
在元素变为可见时激活
 
import { defineAsyncComponent, hydrateOnVisible } from 'vue'
const AsyncComp = defineAsyncComponent({
loader: () => import('./Comp.vue'),
hydrate: hydrateOnVisible()
})
自定义策略
 
import { defineAsyncComponent, type HydrationStrategy } from 'vue'
const myStrategy: HydrationStrategy = (hydrate, forEachElement) => {
// forEachElement 是一个遍历组件未激活的 DOM 中所有根元素的辅助函数,
// 因为根元素可能是一个片段而非单个元素
forEachElement(el => {
// ...
})
// 准备好时调用 `hydrate`
hydrate()
return () => {
// 如必要,返回一个销毁函数
}
}
const AsyncComp = defineAsyncComponent({
loader: () => import('./Comp.vue'),
hydrate: myStrategy
})
其他

请查看 Vue3官方文档 - 惰性激活,这里不再赘述

useId() 生成唯一应用ID

用于为无障碍属性或表单元素生成每个应用内唯一的 ID。在我们日常应用中,主要可以解决服务端和客户端生成的id不一样导致渲染报错的问题

 
<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

如果客户端值不可避免地与其服务端对应值(例如日期)不同,我们可以使用属性 data-allow-mismatch 来避免由此产生的激活不匹配警告

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

还可以指定特定类型。允许的值有:textchildren (仅允许直接子组件不匹配),classstyleattribute

其他

useTemplateRef()

返回一个浅层 ref,可以更直观的绑定元素,同时也支持动态绑定

 
<script setup>
import { ref, useTemplateRef, onMounted } from 'vue'
const targetRef = ref('input1')
const inputRef = useTemplateRef<HTMLInputElement>(targetRef.value)
onMounted(() => {
inputRef.value.focus()
})
</script>
<template>
<input ref="input1" />
<input ref="input2" />
</template>

其他不常用的就不在说明了

   

   关注灵活就业新业态,关注公账号:贤才宝(贤才宝https://www.51xcbw.com)


http://www.kler.cn/a/534532.html

相关文章:

  • iOS 老项目适配 #Preview 预览功能
  • Windows Docker笔记-安装docker
  • Java 大视界 -- Java 大数据在智慧文旅中的应用与体验优化(74)
  • 【multi-agent-system】ubuntu24.04 安装uv python包管理器及安装依赖
  • 从BIO到NIO:Java IO的进化之路
  • 每日一题洛谷P5721 【深基4.例6】数字直角三角形c++
  • 一、tsp学习笔记——开发环境搭建
  • 计算机网络笔记再战——理解几个经典的协议6——TCP与UDP
  • Mysql-增删改查(知识点总结)
  • WPS的word文档加密
  • module ‘matplotlib.cm‘ has no attribute ‘get_cmap‘
  • 在https下引用IC卡读卡器web插件
  • LeetCode 257.二叉树的所有路径
  • BUU10 [极客大挑战 2019]LoveSQL1
  • RK3576——USB3.2 OTG无法识别到USB设备
  • docker容器编排工具 docker compose
  • 【Elasticsearch】 邻接矩阵聚合(Adjacency Matrix Aggregation)
  • ASP.NET Core中间件Markdown转换器
  • 数据加载器--不同文档数据格式的加载方法
  • seata 1.3.0 本地安装步骤
  • go-zero学习笔记(四)
  • python(自学10-2)获取豆瓣页面 下载成json格式
  • 7.PPT:“中国梦”学习实践活动【20】
  • MySQL常见的存储引擎和区别
  • ASP.NET Core与EF Core的集成
  • 系留无人机通信中继、空地组网技术详解