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

提前解锁 Vue 3.5 的新特性

Vue 3.5 是 Vue.js 新发布的版本,虽然没有引入重大变更,但带来了许多实用的增强功能、内部优化和性能改进。

1. 响应式系统优化

Vue 3.5 进一步优化了响应式系统的性能,并且减少内存占用。尤其在处理大型或深度嵌套的响应式数组时,性能提高了 10 倍。

举个 🌰

<template><div><p v-for="item in deepArray" :key="item.value">{{ item.value }}</p></div>
</template><script setup>
import { reactive } from 'vue'// 创建一个大型的深度嵌套数组,测试响应式系统的优化效果
const deepArray = reactive([...Array(10000)].map(() => reactive({ value: Math.random() })))
</script>

在这个示例中,我们创建了一个包含 10000 个深度嵌套对象的数组。Vue 3.5 对这种场景的内存和性能进行了优化,可以在大量操作和变化时观察到更流畅的响应式处理。

2. 响应式 Props 解构

在 Vue 3.5 中,响应式 props 解构默认启用。在使用 defineProps 时,可以像处理普通 JavaScript 对象那样解构 props,并且解构后的变量保持响应式。

之前的方式:

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

新方式:

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

解构后的变量 count 和 msg 在模板中使用时会自动保持响应式,且不需要显式地调用 toRefs。

但我没有成功在 Vue 3.5 的项目下运行成功,还需要研究一下 o(╥﹏╥)o。

3. 服务器渲染(SSR)改进

3.1 懒加载补水(Lazy Hydration)

Vue 3.5 引入了懒加载补水功能,使用 defineAsyncComponent() 可以控制异步组件的水合时机。例如:允许异步组件在首次可见时才进行补水操作,减少初次渲染的资源消耗。

3.1.1 解释一下补水(水合操作)!!

补水(Hydration)是一个与服务器端渲染(SSR)相关的术语。

在 SSR 中,Vue 会在服务器上预先渲染组件的 HTML,并将其发送到浏览器。当页面加载时,客户端的 JavaScript 代码会接管这些已经存在的 HTML 元素,并将它们变为动态响应式,这个过程就被称为水合操作(Hydration)

补水(水合操作)的意义

水合操作的主要目的是将服务器端预渲染的静态 HTML 客户端的动态 JavaScript 逻辑连接起来,使页面在首次加载时可以快速显示内容,同时在客户端加载完 JavaScript 之后,页面可以正常交互。这种做法提高了页面的首次加载速度用户体验,特别是在网络环境较差或页面较为复杂时。

补水与懒加载补水

1、普通补水

页面加载时,所有的静态 HTML 会立即被客户端 JavaScript "接管"。这种做法可能会导致在页面初次渲染时,客户端需要同时处理大量的水合任务,从而影响性能。

2、懒加载补水

Vue 3.5 引入的懒加载补水功能指,只在组件首次出现在视口中时才进行水合操作。这样可以减少页面初次渲染时的性能开销,只在需要时才补水,特别适合异步加载的组件或在页面滚动到可见区域时才需要的内容。

举个 🌰

假设我们有一个异步加载的组件 AsyncComponent.vue,在普通补水情况下,这个组件在 SSR 中生成的 HTML 会在页面加载时立即被水合,无论用户是否滚动到该组件的可见区域。而在懒加载补水的情况下,只有当用户滚动到组件可见时,才会触发水合。

App.vue

<template><div class="container"><AsyncComp v-if="visible" /><button @click="toggleVisibility">Toggle Component</button></div>
</template><script setup>
import { ref } from 'vue'
import { defineAsyncComponent, hydrateOnVisible } from 'vue'const visible = ref(false)
const toggleVisibility = () => {visible.value = !visible.value
}
const AsyncComp = defineAsyncComponent({loader: () => import('./components/AsyncComponent.vue'), // 模拟异步加载的组件hydrate: hydrateOnVisible() // 只有在组件可见时才进行水合
})
</script>

AsyncComponent.vue  

<template><div>异步加载的组件</div>
</template>

展示为:

3.2 useId( ) API

useId( ) 是一个新 API,专门为生成在服务器和客户端渲染过程中保持稳定的唯一 ID。这对于生成表单元素和可访问性属性的 ID 非常有用。

举个 🌰

<template><form><label :for="id">Name:</label><input :id="id" type="text" /></form>
</template><script setup>
import { useId } from 'vue'
// 使用 useId 生成一个唯一的 id
const id = useId()
console.log("~ id:", id)
</script>

此功能确保生成的 ID 在 SSR 和客户端渲染时保持一致,确保表单和可访问性属性不会因不匹配导致警告或错误。

4. 自定义元素改进 

Vue 3.5 对 defineCustomElement() API 进行了增强,使 Vue 创建 Web Components 更加灵活。

举个 🌰 App.vue

<template><div class="container"><!-- Vue 自定义元素可以像普通 HTML 元素一样使用 --><my-element title="使用自定义元素" description="这是通过 Vue 定义的 Web Component。"></my-element><br /><my-element /></div>
</template><script setup>
import { defineCustomElement } from 'vue'
import MyElement from './components/MyElement.ce.vue'// 使用 defineCustomElement 注册组件
const MyElementCustom = defineCustomElement(MyElement, {shadowRoot: false,
})
// 通过 customElements.define 注册为自定义元素
customElements.define('my-element', MyElementCustom)
</script>

MyElement.ce.vue

<template><div><h1>{{ title }}</h1><p>{{ description }}</p></div>
</template><script>
export default {props: {title: {type: String,default: '默认标题'},description: {type: String,default: '这是自定义元素的描述内容'}}
}
</script>

 展示为:

4.1 解释一下 .ce.vue

在 Vue.js 中,.ce.vue 文件名中的.ce 通常表示自定义元素(Custom Element)。这种命名方式并不是 Vue 官方强制要求的,而是一种约定俗成的命名规范,用于区分普通的 Vue 组件和用来创建Web Components的自定义元素组件。

自定义元素在许多场景中很有用,特别是希望在多个框架之间共享组件,或者希望组件能够独立运行时,Web Components 是一个很好的选择。而 .ce.vue 文件命名则帮助开发者清楚地知道这个 Vue 组件是为生成 Web Components 而设计的。

5. 新增 useTemplateRef( )

Vue 3.5 引入了 useTemplateRef() API,它允许动态地获取模板引用,特别适用于引用 ID 动态变化或条件变化的场景。相较于传统的 ref,useTemplateRef 可以在运行时根据不同的条件动态更新引用,而不是依赖于静态的 ref 属性。

举个 🌰

<template><input ref="inputRef" type="text" />
</template><script setup>
import { useTemplateRef } from 'vue'// 获取动态引用的 input
const inputRef = useTemplateRef('inputRef')// 在生命周期中可以访问这个引用
onMounted(() => {inputRef.value.focus()
})
</script>

6. 延迟传送(defer Teleport)

Vue 内置 <Teleport> 组件在传送内容时,要求目标元素在组件挂载时已经存在。Vue 3.5 引入了 defer 属性,许传送内容到后才渲染的目标元素。

举个 🌰

<template><div class="container"><Teleport defer to="#dynamic-target"><p>传送内容...</p></Teleport><div id="dynamic-target"></div></div>
</template><script setup>
import { onMounted } from 'vue'
onMounted(() => {setTimeout(() => {// 模拟目标元素动态渲染document.getElementById('dynamic-target').innerHTML = '<div>目标元素已渲染</div>'}, 1000)
})
</script>

展示为: 

这里 Teleport 组件会等待目标元素(#dynamic-target)渲染后再将内容传送过去,可以解决传送目标先于组件渲染的问题。

7. 新增 onWatcherCleanUp()

Vue 3.5 引入了 onWatcherCleanup() API,用于在清理 watch 时注册回调函数。例如,可以在 watch 的回调中清理过时的网络请求。

举个 🌰

<template><div><button @click="id++">更改 ID</button><p>当前 ID: {{ id }}</p></div>
</template><script setup>
import { ref, watch, onWatcherCleanup } from '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(() => {controller.abort();});
});
</script>

此功能允许在 watch 停止追踪时自动执行清理操作,避免资源泄漏。

8. 总结

Vue 3.5 版本提供了多项增强功能,包括响应式系统的性能优化、响应式 props 解构、SSR 改进、自定义元素支持的扩展等,优化内存、提升性能的同时也提升了 Vue 的开发体验。

有些内容可能不是很详细,大家感兴趣的话,可以自行研究一下。

在此之前:需要确保项目使用的是 Vue 3.5。可以使用以下命令更新项目中的 Vue 版本:

npm install vue@latest
# or
yarn add vue@latest

然后,检查项目中的 package.json,确认 Vue 版本已经更新到 3.5 或更高:

相关文章:

提前解锁 Vue 3.5 的新特性

Vue 3.5 是 Vue.js 新发布的版本&#xff0c;虽然没有引入重大变更&#xff0c;但带来了许多实用的增强功能、内部优化和性能改进。 1. 响应式系统优化 Vue 3.5 进一步优化了响应式系统的性能&#xff0c;并且减少内存占用。尤其在处理大型或深度嵌套的响应式数组时&#xff…...

web基础—dvwa靶场(十)XSS

XSS(DOM) 跨站点脚本&#xff08;XSS&#xff09;攻击是一种注入攻击&#xff0c;恶意脚本会被注入到可信的网站中。当攻击者使用 web 应用程序将恶意代码&#xff08;通常以浏览器端脚本的形式&#xff09;发送给其他最终用户时&#xff0c;就会发生 XSS 攻击。允许这些攻击成…...

搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(五)-聚合

聚合 聚合基于Query结果的统计&#xff0c;执行过程是搜索的一部分&#xff0c;Onesearch支持0代码构建聚合&#xff0c;聚合目前完全在引擎层 0代码聚合 上图是聚合的配置&#xff0c;包括2个pdm文档聚合统计 termsOfExt term桶聚合&#xff0c;统计ext&#xff0c;如&…...

Pandas中df常用方法介绍

目录 常用方法df.columnsdf.indexdf.valuesdf.Tdf.sort_index()df.sort_values() 案例 常用方法 df.columns df.columns 是 Pandas 中 DataFrame 对象的一个属性&#xff0c;用于获取 DataFrame 中的列标签&#xff08;列名&#xff09;。 基本语法如下&#xff1a; df.col…...

LabVIEW中AVI帧转图像数据

在LabVIEW中&#xff0c;有时需要将AVI视频文件的帧转换为图像数据进行进一步处理。下面详细讲解了如何从AVI视频提取单帧并将其转换为图像数据集群&#xff0c;以便与其他图像处理VI兼容。 问题背景&#xff1a; 用户已经拥有能够处理JPEG图像数据集群的VI&#xff0c;现在希…...

并发与并行的区别:深入理解Go语言中的核心概念

在编程中,并发与并行的区别往往被忽视或误解。很多开发者在谈论这两个概念时,常常把它们混为一谈,认为它们都指“多个任务同时运行”。但实际上,这种说法并不完全正确。如果我们深入探讨并发和并行的区别,会发现它不仅是词语上的不同,更是编程中非常重要的抽象层次,特别…...

小小扑克牌算法

1.定义一个扑克牌类Card&#xff1a; package democard; public class Card {public String suit;//表示花色public int rank;//表示牌点数Overridepublic String toString() {return "{"suit rank"}";}//实例方法&#xff0c;初始化牌的点数和花色public…...

【第34章】Spring Cloud之SkyWalking分布式日志

文章目录 前言一、准备1. 引入依赖 二、日志配置1. 打印追踪ID2. gRPC 导出 三、完整日志配置四、日志展示1. 前端2. 后端 总结 前言 前面已经完成了请求的链路追踪&#xff0c;这里我们通过SkyWalking来处理分布式日志&#xff1b; 场景描述&#xff1a;我们有三个服务消费者…...

easy-es动态索引支持

背景 很多项目目前都引入了es&#xff0c;由于es弥补了mysql存储及搜索查询的局限性&#xff0c;随着技术的不断迭代&#xff0c;原生的es客户端使用比较繁琐不直观&#xff0c;上手代价有点大&#xff0c;所以easy-es框架就面世了&#xff0c;学习成本很低&#xff0c;有空大…...

SWC(Speedy Web Compiler)

概述 SWC 由 Rust 编写&#xff0c; 既可用于编译&#xff0c;也可用于打包。 对于编译&#xff0c;它使用现代 JavaScript 功能获取 JavaScript / TypeScript 文件并输出所有主流浏览器支持的有效代码。 SWC在单线程上比 Babel 快 20 倍&#xff0c;在四核上快 70 倍。 简…...

【计算机网络】传输层协议UDP

目录 一、端口号1.1 端口号范围划分1.2 认识知名端口号 二、UDP协议2.1 UDP协议端格式2.2 UDP的特点2.3 UDP的缓冲区2.4 UDP使用注意事项2.5 基于UDP的应用层协议 一、端口号 传输层协议负责数据的传输&#xff0c;从发送端到接收端。端口号标识一个主机上进行通信的不同的应用…...

Docker+PyCharm远程调试环境隔离解决方案

DockerPyCharmMiniconda实现深度学习代码远程调试和环境隔离 本文详细介绍了如何在局域网环境下&#xff0c;利用Docker、PyCharm和Miniconda构建一个高效的深度学习远程调试平台。首先在服务器&#xff08;server&#xff09;上&#xff0c;通过Docker构建包含不同CUDA环境的镜…...

数字化转型的理论框架对比:从多维视角指导企业成功变革对比DPBOKIT4ITCOBITTOGAF

数字化转型的多维框架解析 在数字化时代&#xff0c;企业如何有效实现数字化转型已成为其生存和发展的关键问题。然而&#xff0c;市场上关于数字化管理的各种框架和理论并存&#xff0c;企业需要根据自身的需求选择最适合的指导路径。本文将通过对几个核心理论框架的对比&…...

【C++掌中宝】深入解析C++命名空间:有效管理代码的利器

文章目录 前言1. namespace 的价值2. namespace 的定义3. 命名空间的本质4. 嵌套的命名空间5. 命名空间的使用6. using 指令7. 补充结语 前言 假设这样一种情况&#xff0c;当一个班上有两个名叫 Zara 的学生时&#xff0c;为了明确区分它们&#xff0c;我们在使用名字之外&am…...

2024/9/21 leetcode 21.合并两个有序链表 2.两数相加

目录 21.合并两个有序链表 题目描述 题目链接 解题思路与代码 2.两数相加 题目描述 题目链接 解题思路与代码 --------------------------------------------------------------------------- 21.合并两个有序链表 题目描述 将两个升序链表合并为一个新的 升序 链表并返…...

Python学习的主要知识框架

Python的主要学习知识点非常广泛且深入&#xff0c;但我可以为您概括一些核心的学习领域&#xff0c;帮助您系统地掌握Python编程。以下是Python学习的主要知识框架&#xff1a; 1. Python基础语法 数据类型&#xff1a;整数、浮点数、字符串、布尔值、列表、元组、字典、集合…...

LLaMA-Factory 使用 alpaca 格式的数据集

LLaMA-Factory 使用 alpaca 格式的数据集 flyfish alpaca 格式最初与Stanford大学的一个研究项目相关联&#xff0c;该项目旨在通过少量高质量的数据来微调大型语言模型。它受到了Alpaca模型&#xff08;一种基于LLaMA的指令跟随模型&#xff09;的影响&#xff0c;该模型是在…...

【Mysql】Mysql数据库基础

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…...

一文彻底让你搞懂轨迹规划(总结)

机器人在运行中不可避免的会进行运动&#xff0c;那么就会产生出轨迹规划的概念。 轨迹规划的特点&#xff1a;用一定的函数形式表示控制量&#xff08;位置&#xff0c;速度&#xff0c;加速度&#xff09;的控制律&#xff0c;根据约束或最优目标&#xff0c;求取控制控制参…...

windows C++ 并行编程-异步消息块(二)

overwrite_buffer 类 concurrency::overwrite_buffer 类与 unbounded_buffer 类类似&#xff0c;只不过 overwrite_buffer 对象仅存储一条消息。 此外&#xff0c;当目标接收来自 overwrite_buffer 对象的消息时&#xff0c;不会从缓冲区中删除该消息。 因此&#xff0c;多个目…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...