VUE3.5版本解读

官网:Announcing Vue 3.5 | The Vue Point

2024年9月1日,宣布 Vue 3.5“天元突破:红莲螺岩”发布!

反应系统优化

在 3.5 中,Vue 的反应系统经历了另一次重大重构,在行为没有变化的情况下实现了更好的性能和显著改善的内存使用率(-56%)。重构还解决了 SSR 期间计算值挂起导致的过时计算值和内存问题。此 PR 重构了核心反应系统,以使用版本计数和受Preact 信号启发的双向链表数据结构。

此外,3.5 还优化了大型、深度反应阵列的反应性跟踪,在某些情况下可使此类操作速度提高 10 倍。

内存使用改进

给定一个有 1000 个引用 + 2000 个计算(1000 个链接对)+ 1000 个订阅最后一个计算的效果的测试用例,比较这些类实例使用的总内存:

  • 之前(3.4.19):1426k
  • 之后(此 PR):631k(-56%)

计算现在也仅在自身获得第一个订阅者时才延迟订阅 deps,并在失去所有订阅者时取消订阅。这意味着它们可以更可靠地进行垃圾收集,包括在 SSR 中。

响应式 Props 解构

在 Vue 3.5 中,响应式 props 的解构功能已经稳定下来,并且默认启用。这意味着在 <script setup> 中从 defineProps 解构的变量现在具有响应性。这一改进大大简化了使用默认值声明 props 的过程,并且利用了 JavaScript 的原生默认值语法。

<template><div><p>Name: {{ name }}</p><p>Age: {{ age }}</p><button @click="incrementAge">Age +1</button></div>
</template><script setup>
import { ref, watch } from 'vue';// 定义属性
const props = defineProps({name: {type: String,default: 'John'},age: {type: Number,default: 30}
});// 创建响应式数据
const age = ref(props.age);// 监听属性变化
watch(() => props.age, (newAge) => {age.value = newAge;
});// 更新年龄的方法
const incrementAge = () => {age.value++;
};
</script>

解构 props 变量(例如 count)的访问会被编译器自动编译成 props.count,从而保持响应性。这意味着当我们访问解构后的变量时,Vue 会自动对其进行跟踪。 如果需要在保留响应性的同时监视解构的 prop 变量或将其传递到可组合函数中,需要将其包装在 getter 中。这一改进使得处理 props 变得更加直观和高效。

这一改进大大简化了代码,使得 props 的声明和使用更加直观和简洁。我们不再需要使用 toRefs 或其他复杂的模式来保持响应性。

SSR 改进

在 Vue 3.5 中,服务器端渲染(SSR)得到了一些重要的改进,特别是在懒惰水合、useId() API 和 data-allow-mismatch 属性方面。这些改进旨在提高 SSR 的性能、稳定性和开发体验。

懒惰水合(Lazy Hydration)

控制水合策略

在 Vue 3.5 中,异步组件的水合策略可以通过 defineAsyncComponent API 的 hydrate 选项来控制。懒惰水合是指组件在首次渲染时不会立即进行水合(hydration),而是在某些条件满足时(例如组件可见时)才进行水合。

import { defineAsyncComponent } from 'vue';const LazyComponent = defineAsyncComponent({loader: () => import('./MyComponent.vue'),hydrate: {when: 'visible', // 仅在组件可见时进行水合},
});

核心 API 设计得较低级别,而 Nuxt 团队已在此特性的基础上构建了更高级别的语法糖,使得懒惰水合的实现更加简单和直观。

useId() API

useId() 是一个 API,可用于生成每个应用程序唯一的 ID。这些 ID 在服务器和客户端渲染过程中保持稳定,确保不会导致水合不匹配。

import { useId } from 'vue';const uniqueId = useId();

应用场景

这些唯一 ID 可用于生成表单元素和可访问性属性的 ID,确保在 SSR 应用程序中使用时不会导致水合不匹配。

data-allow-mismatch 属性

抑制水合不匹配警告,在某些情况下,客户端值不可避免地与服务器对应值不同(例如日期)。Vue 3.5 引入了 data-allow-mismatch 属性,用于抑制由此产生的水合不匹配警告。

<div data-allow-mismatch><!-- 内容 -->
</div>

还可以通过为 data-allow-mismatch 属性提供值来限制允许的不匹配类型。可能的值包括 text、children、class、style 和 attribute。

<div data-allow-mismatch="text"><!-- 内容 -->
</div>

自定义元素改进

在 Vue 3.5 中,自定义元素(Custom Elements)得到了显著的改进,修复了许多与 defineCustomElement API 相关的长期存在的问题,并添加了许多新功能。这些改进使得使用 Vue 创建自定义元素更加灵活和强大。

自定义元素的应用程序配置

通过选项支持自定义元素的应用程序配置,在 Vue 3.5 中,你可以通过 configureApp 选项来配置自定义元素的应用程序。这使得你可以在定义自定义元素时进行更细粒度的配置。

import { defineCustomElement } from 'vue';const MyElement = defineCustomElement({// 组件选项template: '<div>Hello, World!</div>',configureApp: (app) => {// 配置应用程序app.config.globalProperties.$myGlobal = 'global value';},
});customElements.define('my-element', MyElement);

访问宿主元素和影子根

添加 useHost()、useShadowRoot() 和 this.$host API,Vue 3.5 添加了 useHost() 和 useShadowRoot() 组合函数,以及 this.$host API,用于访问自定义元素的宿主元素和影子根。

import { defineCustomElement, useHost, useShadowRoot } from 'vue';const MyElement = defineCustomElement({setup() {const host = useHost();const shadowRoot = useShadowRoot();console.log('Host Element:', host.value);console.log('Shadow Root:', shadowRoot.value);return () => <div>Hello, World!</div>;},
});customElements.define('my-element', MyElement);

支持安装没有 Shadow DOM 的自定义元素

通过传递 shadowRoot: false 支持安装没有 Shadow DOM 的自定义元素,在 Vue 3.5 中,你可以通过传递 shadowRoot: false 选项来支持安装没有 Shadow DOM 的自定义元素。

import { defineCustomElement } from 'vue';const MyElement = defineCustomElement({template: '<div>Hello, World!</div>',shadowRoot: false, // 不使用 Shadow DOM
});customElements.define('my-element', MyElement);

支持提供 nonce 选项

支持提供一个 nonce 选项,该选项将附加到 <style> 自定义元素注入的标签上,Vue 3.5 支持提供一个 nonce 选项,该选项将附加到 <style> 自定义元素注入的标签上,以增强安全性。

import { defineCustomElement } from 'vue';const MyElement = defineCustomElement({template: '<div>Hello, World!</div>',nonce: 'my-nonce-value', // 设置 nonce 值
});customElements.define('my-element', MyElement);

仅自定义元素选项

通过第二个参数传递仅自定义元素选项,在 Vue 3.5 中,你可以通过第二个参数传递仅自定义元素选项,以进一步定制自定义元素的行为。

import { defineCustomElement } from 'vue';const MyElement = defineCustomElement({template: '<div>Hello, World!</div>',},{shadowRoot: false, // 不使用 Shadow DOMnonce: 'my-nonce-value', // 设置 nonce 值}
);customElements.define('my-element', MyElement);

其他显著特点

useTemplateRef() API

获取模板引用的新方法

Vue 3.5 引入了一种通过 useTemplateRef() API 获取模板引用的新方法。这种方法通过运行时字符串 ID 匹配引用,因此支持动态引用绑定到变化的 ID。

<template><div><input ref="inputRef" type="text" /></div>
</template><script setup>
import { useTemplateRef } from 'vue';const inputRef = useTemplateRef('inputRef');console.log(inputRef.value); // 获取 input 元素的引用
</script>

与旧方法的对比

在 3.5 之前,我们建议使用变量名与静态 ref 属性匹配的普通引用。旧方法要求 ref 属性可由编译器分析,因此仅限于静态 ref 属性。相比之下,useTemplateRef() 通过运行时字符串 ID 匹配引用,因此支持动态引用绑定到变化的 ID。

语言工具支持

@vue/language-tools 2.1 还实现了对新语法 useTemplateRef() 的特殊支持,因此在使用时您将根据 ref 模板中存在的属性获得自动完成和警告。

延迟传送(Deferred Teleport)

内置 <Teleport> 组件的限制

内置 <Teleport> 组件的一个已知限制是,其目标元素必须在传送组件挂载时存在。这阻止用户在传送后将内容传送到 Vue 渲染的其他元素。

引入 defer prop

在 Vue 3.5 中,我们引入了一个 defer prop,用于在当前渲染周期之后挂载 <Teleport>,因此现在可以正常工作:

<template><div><Teleport to="#target" defer><div>Teleported Content</div></Teleport></div>
</template><script setup>
import { Teleport } from 'vue';
</script>

默认行为

此行为需要 defer prop,因为默认行为需要向后兼容。

onWatcherCleanup() API

在观察者中注册清理回调

Vue 3.5 引入了一个全局导入的 API onWatcherCleanup(),用于在观察者中注册清理回调。

import { watch, onWatcherCleanup } from 'vue';watch(() => someValue,(newValue, oldValue, onCleanup) => {const cleanup = () => {// 清理逻辑};onWatcherCleanup(cleanup);}
);

应用场景

onWatcherCleanup() 可以在观察者中注册清理回调,确保在观察者被停止或重新运行时执行清理逻辑,避免内存泄漏和其他潜在问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/55412.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS/OpenHarmony 如何将rawfile中文件复制到沙箱中

关键词&#xff1a;h5离线加载、HarmonyOS、OpenHarmony、文件操作、复制、解压 当下有一个场景&#xff0c;需要离线加载 h5离线资源zip包&#xff0c;并实现资源包的动态更新&#xff0c;那么仅靠 $rawfile并不能实现该功能&#xff0c;那么我们该如何实现&#xff1f; 我们…

在线代码编辑器

在线代码编辑器 文章说明前台核心代码后台核心代码效果展示源码下载 文章说明 采用Java结合vue3设计实现的在线代码编辑功能&#xff0c;支持在线编辑代码、运行代码&#xff0c;同时支持导入文件&#xff0c;支持图片识别&#xff0c;支持复制代码&#xff0c;可将代码导出为图…

【项目开发】跨专业合作平台实战(附源码)

原创文章,禁止转载。 文章目录 项目背景+项目需求开发语言及环境数据库构建项目介绍+项目展示1、用户注册界面(register.php)2、用户登录界面(login.php)3、项目大厅界面(project_hall.php)4、标签详情界面(tag_detail.php)5、项目详情界面(project_detail.php)6、发起招募界面…

【mod分享】侠盗猎魔2冬日mod,贴图高清化,增加下雪场景,支持光追,并且增加红色霓虹灯

今天小编为大家带来一个新的游戏mod&#xff0c;这次mod主要是修改了游戏《侠盗猎魔2》&#xff0c;我给游戏增加了下雪的场景&#xff0c;并且增加了红色的霓虹灯&#xff0c;整体让游戏沉浸在一种诡异的圣诞气氛中。并且我还提高了游戏材质的分辨率。更多细节需要玩家自己探索…

[高频题]Leetcode 815 Bus route

题意 给定数组routes&#xff0c;代表每一辆车能够到达哪些车站&#xff0c;求最少需要多少次中转我才能够到达终点 https://leetcode.com/problems/bus-routes/description/ routes [[1,2,7],[3,6,7]], source 1, target 6 answer 2 理论上我应该建立车站到车站&#xf…

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【下篇】

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【下篇】 一、上篇回顾二、项目准备2.1 准备模板项目2.2 支持计时功能2.3 配置UART4引脚2.4 支持printf重定向到UART42.5 支持printf输出浮点数2.6 支持printf不带\r的换行2.7 支持ccache编译缓存 三、TFLM集成3.1 添加tfli…

设计模式-策略模式-200

优点&#xff1a;用来消除 if-else、switch 等多重判断的代码&#xff0c;消除 if-else、switch 多重判断 可以有效应对代码的复杂性。 缺点&#xff1a;会增加类的数量&#xff0c;有的时候没必要为了消除几个if-else而增加很多类&#xff0c;尤其是那些类型又长又臭的 原始代…

【Go】-基于Gin框架的IM通信项目

目录 项目介绍 项目分析 项目分层 初始化 首页功能 获取首页 注册 进入聊天界面 用户模块 创建用户 删除用户 修改用户信息 查找用户 通过名字和密码查找用户 获取用户列表 好友模块 获取所有好友 添加好友 发送消息 ws升级和订阅redis管道接收消…

深入理解JavaScript 的原型继承

JavaScript 的原型链继承机制和 Java 的类继承机制有明显的区别&#xff0c;虽然它们都用于实现对象之间的继承&#xff0c;但它们的实现方式、概念以及运行机制都不同。 1. JavaScript 的原型继承 JavaScript 是基于原型链的继承&#xff0c;主要依赖对象的 __proto__ 属性或…

小鱼ROS2 g++编译报错

把humble换成jazzy &#xff0c;起初报错 /opt/ros/jazzy/include/rcl_interfaces/rcl_interfaces/srv/detail/list_parameters__struct.hpp:267:10: fatal error: service_msgs/msg/detail/service_event_info__struct.hpp: 没有那个文件或目录 267 | #include "servi…

基于单片机远程家电控制系统设计

本设计基于单片机的远程家电控制系统&#xff0c;以STC89C52单片机为核心&#xff0c;通过液晶LCD1602实时显示并控制&#xff0c;利用ESP8266WiFi模块实现本地与云平台的连接&#xff0c;最终实现远程对于灯光&#xff0c;热水器等家电的开关控制。同时&#xff0c;系统设有防…

MongoDB 聚合管道

参考: 聚合管道 - MongoDB 手册 v7.0 介绍 聚合管道由一个或多个处理文档的阶段组成&#xff1a; 每个阶段对输入文档执行一个操作。例如&#xff0c;某个阶段可以过滤文档、对文档进行分组并计算值。 从一个阶段输出的文档将传递到下一阶段。 一个聚合管道可以返回针对文档…

HTB:Oopsie[WriteUP]

目录 连接至HTB服务器并开启靶机 1.With what kind of tool can intercept web traffic? 2.What is the path to the directory on the webserver that returns a login page? 3.What can be modified in Firefox to get access to the upload page? 4.What is the acc…

html+css+js实现step进度条效果

实现效果 代码实现 HTML部分 <div class"box"><ul class"step"><li class"circle actives ">1</li><li class"circle">2</li><li class"circle">3</li><li class&quo…

【设计模式-模板】

定义 模板方法模式是一种行为设计模式&#xff0c;它在一个方法中定义了一个算法的骨架&#xff0c;并将一些步骤延迟到子类中实现。通过这种方式&#xff0c;模板方法允许子类在不改变算法结构的情况下重新定义算法中的某些特定步骤。 UML图 组成角色 AbstractClass&#x…

python编程开发“人机猜拳”游戏

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

回归预测 | Matlab基于SABO-SVR减法平均算法优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于SABO-SVR减法平均算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SABO-SVR减法平均算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于SABO-SVR减法平均算法优化…

如何创建一个docker,给它命名,且下次重新打开它

1.创建一个新的docker并同时命名 docker run -it --name one ubuntu:18.04 /bin/bash 这时候我们已经创建了一个docker,并且命名为"one" 2.关闭当前docker exit 3.这时docker已经终止了&#xff0c;我们需要使用它要重新启动 docker start one 4.现在可以重新打…

哈希表(HashMap、HashSet)

文章目录 一、 什么是哈希表二、 哈希冲突2.1 为什么会出现冲突2.2 如何避免出现冲突2.3 出现冲突如何解决 三、模拟实现哈希桶/开散列&#xff08;整型数据&#xff09;3.1 结构3.2 插入元素3.3 获取元素 四、模拟实现哈希桶/开散列&#xff08;泛型&#xff09;4.1 结构4.2 插…

QSqlDatabase在多线程中的使用

Qt中多线程使用数据库_qt数据库管理类支持多数据库,多线程-CSDN博客 1. 代码&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlError>…