目录
前言
Vue3.5
在2024-09-03
正式上线,目前在 Vue
官网显最新版本已经是 Vue3.5
,其中主要包含了几个小改动,完整的过往发布记录可以在 GitHub 查阅。
一、带响应式 Props 解构赋值
简述:以前我们对 Props 直接进行解构赋值是会失去响应式的,需要配合使用 toRefs 或者 toRef 解构才会有响应式,那么就多了 toRefs 或者 toRef 这工序,而最新 Vue3.5 版本已经不需要了。
这样直接解构,testCount 能直接渲染显示,但会失去响应式,当我们修改 testCount 时页面不更新。
<template>
<div>
{{ testCount }}
</div>
</template>
<script setup>
import { definProps } from 'vue';
const props = definProps({
testCount: {
type: Number,
default: 0,
},
});
</script>
保留响应式老式的写法,使用 toRefs 或者 toRef 解构
<template>
<div>
{{ testCount }}
</div>
</template>
<script setup>
import { definProps, toRefs, toRef } from 'vue';
const props = definProps({
testCount: {
type: Nmuber,
default: 0,
},
});
const { testCount } = toRefs(props);
//或者
const testCount = toRef(props,'testCount')};
</script>
最新 Vue3.5 写法,依然保留响应式
<template>
<div>
{{ testCount }}
</div>
</template>
<sceipt setup>
import { definProps } from 'vue';
const { testCount } = definProps({
testCount {
type: Number,
},
});
</script>
相对以前便捷了,直接解构使用省去了 toRefs 或者 toRef
二、Props 默认值新写法
简述: 以前默认值都是用 default: ***
去设置,现在不用了,现在只需要解构的时候直接设置默认值,不需要额外处理。
先看看旧的
default: ***
默认值写法
如下第12
就是旧写法,其它以前 Vue2
也是这样设置默认值
<template>
<div>
{{ props.testCount }}
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
testCount: {
type: Number,
default: 1
},
});
</script>
最新优化的写法 如下第9
行,解构的时候直接一步到位设置默认值,更接近js
语法的写法。
<template>
<div>
{{ testCount }}
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const { testCount=18 } = defineProps({
testCount: {
type: Number,
},
});
</script>
三、 useTemplateRef 函数
简述: unseTemplateRef 在之前获取 dom 节点需要给 dom 绑定上一个 ref='refKey',然后再用一个定义 ref 一个空的响应式属性赋值给这个 refKey ,如下所示:
<template>
<div class="content" ref='myNode'>dom</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const myNode = ref(null)
onMounted(()=>{
console.log(myNode) //拿到 dom 节点
})
</script>
而现在,有了 unseTemplateRef 函数,我们可以更好的区分响应式属性和 dom 节点,不像之前响应式属性和 dom 节点都是通过 ref 和定义获取。
最新 Vue3.5 写法 unseTemplateRef 用法如下
<template>
<span style="color: red" ref="myNode">是我</span>
</template>
<script setup>
import { unseTemplateRef } from 'vue';
const node = unseTemplateRef("myNode");
//这里定义的接收 dom 节点的变量无需和 ref 一样,随意定义接收
onMounted(()=>{
console.log(node) //拿到 dom 节点
})
</script>
四、新增 useId()
简述:useId() 是一个 API,用于生成在服务器和客户端渲染之间保持稳定的唯一应用程序 ID。这些 ID 可用于生成表单元素和无障碍属性的 ID。
<template>
<el-form>
<el-label :for="id">Name:</el-label>
<el-input :id="id" type="text" />
</el-form>
</template>
<script setup>
import { useId } form 'vue'
// 使用 useId 生成一个唯一的 id
const id = useId()
</script>
五、延迟传送(defer Teleport)
简述:Vue 内置 <Teleport> 组件在传送内容时,要求目标元素在组件挂载时已经存在。Vue 3.5 引入了 defer 属性,许传送内容到后才渲染的目标元素。
当使用 Teleport 组件时,指定的目标元素(即 to 属性所指向的选择器对应的元素)必须在页面的DOM(文档对象模型)结构中已经存在,否则 Teleport 就无法将内容传送过去。
比如,如果使用 <teleport to="#my-target">,但是页面中没有一个具有 id="my-target" 的元素,Teleport 就无法正常工作,因为找不到传送内容的目标位置。
代码如下:
<template>
<div class="container">
<Teleport defer to="#my-target">
<p>传送内容...</p>
</Teleport>
</div>
<div id="my-target"></div>
</template>
<script setup>
import { onMounted } form 'vue';
onMounted(() => {
setTimeout(() => {
//模拟目标元素动态渲染
docunment.getElementById('my-target').innerHTML = '<div>目标元素已渲染</div>'
},1000)
})
</script>
Vue 3.5 中可以通过 defer 来延迟 Teleport 的挂载,它会等到同一更新周期中的所有其他 DOM 内容都渲染完毕后,再定位目标容器并挂在其子容器。
六、 新增 onWatcherCleanUp()
Vue 3.5 引入了 onWatcherCleanup() API,用于在清理 watch 时注册回调函数。例如,可以在 watch 的回调中清理过时的网络请求。
<template>
<div>
<el-button @click="id++">更改 ID </el-button>
<p>当前 ID: {{ id }}</p>
</div>
</template>
<script setup>
import { ref, watch, onWatcherCleanUp } form 'vue';
const id = ref(1);
//监控 id 的变化,并在watcher 停止时清理过时的网络请求
watch(id, (newId) => {
const controller = new AbortController();
//发起网络请求
fetch(`/api/data/${newId}`,{signal:controller.signal })
// 回调事件
.then((response) => {
if (!response.ok) {
throw new Error (`网络请求失败: ${response.status}`);
}
return response.json(); //解析JSON
})
.then((data) => {
console.log('获取的数据:', data);
})
.catch((error) => {
if (error.name === 'AbortError') {
console.log('请求被取消');
} else {
console.error ('发生错误:', error);
}
});
//注册清理函数,取消旧的请求
onWatcherCleanUp(() => {
// 如果 id 在请求完成之前发生更改,会取消之前的请求
controller.abort();
});
});
</script>
此功能允许在 watch 停止追踪时自动执行清理操作,避免资源泄漏。
注意:onWatcherCleanup 仅在 Vue 3.5+ 中受支持,并且必须在同步执行 watchEffect 函数或 watch 回调函数期间调用:不能在异步函数中的 await 语句之后调用它。
vue3.5 之前中也可以使用 onCleanup
函数作为第 3 个参数传递给 watch 函数:
watch(id, (newId, oldId, onCleanup) => {
// ...
onCleanup(() => {
// 清除逻辑
})
})
watchEffect((onCleanup) => {
// ...
onCleanup(() => {
// 清除逻辑
})
})
如果那里写的不对或者有更好建议欢迎大佬指点,感谢你们的关注以及点赞~