VUE3.5版本解读

news2024/10/1 19:28:25

官网: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 DOM
    nonce: '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.coloradmin.cn/o/2183006.html

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

相关文章

Another redis desktop manager使用说明

Another redis desktop manager使用说明 概述界面介绍图示说明连接界面设置界面查看操作日志主界面信息进入redis-cli控制台更多 概述 Another Redis Desktop Manager是一个开源的跨平台 Redis 客户端&#xff0c;提供了简洁易用的图形用户界面&#xff08;GUI&#xff09;&am…

第5篇:勒索病毒自救指南----应急响应篇

经常会有一些小伙伴问&#xff1a;中了勒索病毒&#xff0c;该怎么办&#xff0c;可以解密吗&#xff1f; 第一次遇到勒索病毒是在早几年的时候&#xff0c;客户因网站访问异常&#xff0c;进而远程协助进行排查。登录服务器&#xff0c;在站点目录下发现所有的脚本文件及附件…

【JaveEE】——多线程中使用顺序表,队列,哈希表

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;多线程环境使用ArrayList 引入&#xff1a; 1&#xff1a;顺序表使用同步机制 2&…

Linux服务器配置anaconda3,下载torch

如图&#xff0c;vscode连接远程服务器后&#xff0c;如下所示&#xff1a; 下载 Anaconda 下载及安装 进入下载官网&#xff0c;点击linux&#xff0c; 下载方式有两种&#xff0c; 直接下载安装包&#xff0c;下载完上传服务器&#xff0c;并安装&#xff0c;安装执行b…

【算法系列-链表】移除链表元素

【算法系列-链表】移除链表元素 欢迎来到【算法系列】第二弹 &#x1f3c6; 链表&#xff0c;接下来我们将围绕链表这类型的算法题进行解析与练习&#xff01;一起加油吧&#xff01;&#xff01;( •̀ ω •́ )✧✨ 文章目录 【算法系列-链表】移除链表元素1. 算法分析&am…

Spring Data(学习笔记)

JPQL语句&#xff1f;&#xff1f;&#xff1f;&#xff08;Query括号中的就是JPQL语句&#xff09; 怎么又会涉及到连表查询呢&#xff1f; 用注解来实现表间关系。 分页是什么&#xff1f;为什么什么都有分页呢 &#xff1f; 继承&#xff0c;与重写方法的问题 Deque是什么 ?…

线程池:线程池的实现 | 日志

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

C++容器之vector模拟实现(代码纯享版!!!)

目录 前言 一、头文件 .h文件 总结 前言 本文是模拟实现vector部分功能的代码&#xff0c;可以直接拿去使用 一、头文件 .h文件 #include<assert.h> #include<iostream> using namespace std; namespace zz {template<class T>class vector{public:typedef…

C++ set,multiset与map,multimap的基本使用

1. 序列式容器和关联式容器 string、vector、list、deque、array、forward_list等STL容器统称为序列式容器&#xff0c;因为逻辑结构为线性序列的数据结构&#xff0c;两个位置存储的值之间一般没有紧密的关联关系&#xff0c;比如交换一下&#xff0c;他依旧是序列式容器。顺…

STM32器件支持包安装,STLINK/JLINK驱动安装

一、支持包安装 1、离线安装 先下载支持包之后&#xff0c;再进行安装。如下图要安装STM32F1系列&#xff0c;双击 出现如下&#xff0c;会自动锁定安装路径&#xff0c;然后点击下一步&#xff0c;直接安装。 2、在线安装 首先需要电脑联网。如下。先点击第一个红框绿色按钮…

常见的VPS或者独立服务器的控制面板推荐

随着越来越多的企业和个人转向VPS和独立服务器以获得更高的性能和灵活性&#xff0c;选择合适的控制面板变得尤为重要。一个好的控制面板可以大大简化服务器管理&#xff0c;提高工作效率。本篇文章将介绍2024年最值得推荐的VPS控制面板&#xff0c;帮助您做出明智的选择。 1.…

STL容器适配器

欢迎来到本期节目- - - STL容器适配器 适配器模式&#xff1a; 在C中&#xff0c;适配器是一种设计模式&#xff0c;有时也称包装样式&#xff1b; 通过将类自己的接口包裹在一个已存在的类中&#xff0c;使得因接口不兼容而不能在一起工作的类能在一起工作&#xff1b; 也就…

使用VBA快速生成Excel工作表非连续列图片快照

Excel中示例数据如下图所示。 现在需要拷贝A2:A15,D2:D15,J2:J15,L2:L15,R2:R15为图片&#xff0c;然后粘贴到A18单元格&#xff0c;如下图所示。 大家都知道VBA中Range对象有CopyPicture方法可以拷贝为图片&#xff0c;但是如果Range对象为非连续区域&#xff0c;那么将产生10…

详解DHCP服务工作原理及配置案例

一. DHCP概述 DHCP&#xff08;Dynamic Host Configuration Protocol&#xff0c;动态主机配置协议&#xff09;是一个主机IP简化分配管理的TCP/IP协议&#xff0c;用户通过DHCP服务器动态的分配给客户端IP地址及其他环境的配置工作&#xff0c;包括IP地址、子网掩码、网关和…

【NVIDIA】如何使用nvidia-smi命令管理和监控GPU

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

KPConv: Flexible and Deformable Convolution for Point Clouds

Abstract Kernel Point Convolution&#xff08;KPConv&#xff09;是一种点云卷积方法&#xff0c;它可以直接在点云数据上进行操作&#xff0c;无需任何中间的表示形式。方法的核心在于使用核点来定义卷积权重&#xff0c;核点位于欧几里得空间中&#xff0c;并仅对靠近它们…

Spring DI 笔记

目录 1.什么是DI? 2.依赖注入的三种⽅式 2.1属性注⼊ 2.2构造⽅法注⼊ 2.3Setter 注⼊ 2.4三种注⼊优缺点分析 3.Autowired存在问题 1.什么是DI? DI: 依赖注⼊ 依赖注⼊是⼀个过程&#xff0c;是指IoC容器在创建Bean时, 去提供运⾏时所依赖的资源&#xff0c;⽽资源指的…

(JAVA)浅尝关于 “栈” 数据结构

1. 栈的概述&#xff1a; 1.1 生活中的栈 存储货物或供旅客住宿的地方&#xff0c;可引申为仓库、中转站。例如酒店&#xff0c;在古时候叫客栈&#xff0c;是供旅客休息的地方&#xff0c;旅客可以进客栈休息&#xff0c;休息完毕后就离开客栈 1.2计算机中的栈 将生活中的…

第1 章 第一节:基础语法

第1 章 第一节&#xff1a;基础语法 1.1书写规则 1.1.1关键字 在Java语言中&#xff0c;已经定义好的&#xff0c;具有一定的功能和作用的英文单词。所有的关键字都是小写的 在Java中总共有51个关键字&#xff0c;还有两个保留字const\goto. 常见的关键字&#xff1a; if…

User-Agent在WebMagic爬虫中的重要性

对于需要从网站上抓取数据的开发者来说&#xff0c;WebMagic是一个强大的工具。它是一个简单灵活的Java爬虫框架&#xff0c;用于抓取网页数据。在爬虫技术中&#xff0c;User-Agent&#xff08;用户代理&#xff09;是一个关键的HTTP请求头&#xff0c;它告诉服务器关于客户端…