首页 > 其他分享 >一文超详解锁 Vue 3.5新特性

一文超详解锁 Vue 3.5新特性

时间:2024-09-19 11:21:36浏览次数:3  
标签:Vue const 函数 vue watch watchEffect 3.5 组件 详解

前端人的苦恼叕来了,前端技术隔三岔五的更新,学习别想停了,趁着中秋即将来临卷起来吧(说好的中秋假期咱不卷的呢)。就在这个9月,尤大叕更新了,没事,一文总结重要更新,大概更新了以下内容:

  • 响应式重构。性能提升了,内存使用率下降了(56%)

  • 响应式 props 解构

  • 新增 useTemplateRef 函数

  • 服务端渲染SSR主要几个部分:新增useId函数、Lazy Hydration  懒加载水合、data-allow-mismatch

  • 新增 onEffectCleanup函数

  • 新增 base watch 函数

  • 新增 onWatcherCleanup

  • 新增 pause和resume方法

  • 改进的 Suspense支持

1、响应式props支持解构,在之前,我们从 props 中解构出来的是不具备响应式的,需要具备响应式解构需要用到 toRefs 方法包装 props进行解构,而3.5之后,就无需 toRefs 包装了。

<template>  <div>    child值:    <span style="color: red">{{ data }}</span>  </div></template>
<script setup>import { watchEffect } from "vue";const { data } = defineProps(["data"]);   //  仍具备响应式watchEffect(() => {  console.log("data", data);});

2、 useTemplateRef 函数,在之前,我们获取 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>

而现在,有了 useTemplateRef 函数,我们可以更好的区分响应式属性和 dom 节点,不像之前响应式属性和dom节点都是通过ref定义和获取。

useTemplateRef 用法如下

<template>  <span style="color: red" ref="myNode">是我</span></template>
<script setup>import { useTemplateRef } from "vue";const node = useTemplateRef("myNode");    // 这里定义的接收dom节点的变量无需和ref一样,随便定义接收
onMounted(()=>{  console.log(node)    // 拿到 dom 节点})</script>

3,新增onEffectCleanup函数,在组件卸载之前或者下一次watchEffect回调执行之前会自动调用onEffectCleanup函数,有了这个函数后你就不需要在组件的beforeUnmount钩子函数去统一清理一些timer了。比如下面这个场景:​​​​​​​

import { watchEffect, ref } from "vue";import { onEffectCleanup } from "@vue/reactivity";
const flag = ref(true);watchEffect(() => {  if (flag.value) {    const timer = setInterval(() => {      // 做一些事情      console.log("do something");    }, 200);    onEffectCleanup(() => {      clearInterval(timer);    });  }});

4,新增onWatcherCleanup函数,和前面的onEffectCleanup函数类似,在组件卸载之前或者下一次watch回调执行之前会自动调用onWatcherCleanup函数,同样有了这个函数后你就不需要在组件的beforeUnmount钩子函数去统一清理一些timer了。比如下面这个场景:​​​​​​​

import { watch, ref, onWatcherCleanup } from "vue";
watch(flag, () => {  const timer = setInterval(() => {    // 做一些事情    console.log("do something");  }, 200);  onWatcherCleanup(() => {    console.log("清理定时器");    clearInterval(timer);  });});

和onEffectCleanup函数不同的是我们可以从vue中import导入onWatcherCleanup函数。

5,新增了一个base watch函数,这个函数用法和我们熟知的watch API一模一样。区别就是我们之前用的watch API是和Vue组件以及生命周期是一起实现的,他们是深度绑定的。而Vue3.5新增的base watch函数是一个新的函数,他的实现和Vue组件以及生命周期没有一毛钱关系。 

为什么将 watch 重构到 reactivity 模块?

将 watch 函数从 runtime-core 模块重构到 reactivity 模块,是一个深思熟虑的决定。在 Vue 的模块化设计中,reactivity 模块负责响应式系统的实现,而 watch 作为观察响应式数据变化的重要工具,理应与响应式系统紧密集成。

这一重构不仅使得 watch 函数的实现更加合理,也方便了下游项目如 Vue Mini 的使用。在过去,由于 watch 函数位于 runtime-core 模块,下游项目如果需要实现类似功能,往往需要手写或复制粘贴代码。而现在,reactivity 模块直接提供了 watch 函数的实现,大大简化了这些项目的开发工作。 

还有一点就是这个base watch函数对于普通开发者来说没有什么影响,但是对于一些下游项目,比如vuemini来说是受益的。

watch的deep选项支持传入数字,在以前deep选项的值要么是false,要么是true,表明是否深度监听一个对象。在3.5中deep选项支持传入数字了,表明监控对象的深度。

比如下面的这个demo:​​​​​​​

const obj1 = ref({  a: {    b: 1,    c: {      d: 2,      e: {        f: 3,      },    },  },});watch(  obj1,  () => {    console.log("监听到obj1变化");  },  {    deep: 3,  });function changeDeep3Obj() {  obj1.value.a.c.d = 20;}function changeDeep4Obj() {  obj1.value.a.c.e.f = 30;}

在上面的例子watch的deep选项值是3,表明监听到对象的第3层。changeDeep3Obj函数中就是修改对象的第3层的d属性,所以能够触发watch的回调。而changeDeep4Obj函数是修改对象的第4层的f属性,所以不能触发watch的回调。

6,新增pause和resume方法,有的场景中我们可能想在“一段时间中暂停一下”,不去执行watch或者watchEffect中的回调。等业务条件满足后再去恢复执行watch或者watchEffect中的回调。在这种场景中pause和resume方法就能派上用场啦。

下面这个是watchEffect的例子,代码如下:​​​​​​​

<template>  <button @click="count++">count++</button>  <button @click="runner2.pause()">暂停</button>  <button @click="runner2.resume()">恢复</button></template>
<script setup lang="ts">import { watchEffect } from "vue";
const count = ref(0);const runner2 = watchEffect(() => {  if (count.value > 0) {    console.log(count.value);  }});</script>

在上面的demo中,点击count++按钮后理论上每次都会执行一次watchEffect的回调。

但是当我们点击了暂停按钮后就会执行pause方法进行暂停,在暂停期间watchEffect的回调就不会执行了。

当我们再次点击了恢复按钮后就会执行resume方法进行恢复,此时watchEffect的回调就会重新执行。不光watchEffect可以执行pause和resume方法,

watch一样也可以执行pause和resume方法。代码如下:​​​​​​​

const runner = watch(count, () => {  if (count.value > 0) {    console.log(count.value);  }});
runner.pause() // 暂停方法runner.resume() // 恢复方法

7、 useId函数,目的是为每一个 vue 文件创建一个唯一的id,并保证在服务器和客户端渲染中保持稳定,可用于生成表单元素和可访问性属性的 ID,如下所示​​​​​​​

<template> <label :for="id">点我也能聚焦</label> <!-- vue3.4同名简写 --> <input :id type="text" placeholder="Enter text here">  </template>
<script setup>import { useId } from "vue";const id = useId();   console.log(id)     // v:0</script>

8,data-allow-mismatch,SSR中有的时候确实在服务端和客户端生成的html不一致,比如在DOM上面渲染当前时间,代码如下:​​​​​​​

<template>  <div>当前时间是:{{ new Date() }}</div></template>

这种情况是避免不了会出现前面useId例子中的那种警告,有代码洁癖的我看着是真不爽。此时我们可以使用data-allow-mismatch属性来干掉警告,代码如下:​​​​​​​

<template>  <div data-allow-mismatch>当前时间是:{{ new Date() }}</div></template>

9,Teleport组件新增defer延迟属性,Teleport 指令允许我们将 DOM 节点渲染到文档中的任意位置,这对于模态框或提示等元素特别有用。Vue 3.5 增强了 Teleport 的功能,使其可以更方便地管理目标节点。​​​​​​​

<div id="target"></div><Teleport to="#target">被传送的内容</Teleport>

文案被传送的内容最终会渲染在id="target"的div元素中。在之前有个限制,就是不能将<div id="target">放在Teleport组件的后面。

这个也很容易理解DOM是从上向下开始渲染的,如果先渲染到Teleport组件。然后就会去找id的值为target的元素,如果找不到当然就不能成功的将Teleport组件的子节点传送到target的位置。

在3.5中为了解决这个问题,在Teleport组件上新增了一个defer延迟属性。加了defer延迟属性后就能将target写在Teleport组件的后面,代码如下:

​​​​​​​

<Teleport defer to="#target">被传送的内容</Teleport><div id="target"></div>

defer延迟属性的实现也很简单,就是等这一轮渲染周期结束后再去渲染Teleport组件。所以就算是target写在Teleport组件的后面,等到渲染Teleport组件的时候target也已经渲染到页面上了。

10,Suspense 组件是一个用于处理异步组件加载和渲染时延迟的有效工具。Vue 3.5 对 Suspense 的实现进行了优化,使得在等待异步数据时的用户体验更好。

<template>  <Suspense>    <template #default>      <AsyncComponent />    </template>    <template #fallback>      <div>Loading...</div>    </template>  </Suspense></template>
<script>import { defineAsyncComponent } from 'vue';const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'));export default { components: { AsyncComponent } };</script>

总结

对于开发者来说Vue3.5版本中还是新增了许多有趣的功能的, 这些功能在一些特殊场景中还是很有用的,总的来说这次的更新都是些小优化,没什么杀手级的特性,所以前端人们不用过于焦虑了吧。

原文链接

标签:Vue,const,函数,vue,watch,watchEffect,3.5,组件,详解
From: https://blog.csdn.net/qq_36799762/article/details/142355373

相关文章

  • 基于SpringBoot + Vue的大学生平时成绩量化管理系统(角色:学生、教师、管理员)
    文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例八、一站式毕设支持服务结语......
  • docker compose.yml 文件属性详解
    dockercompose.yml文件属性详解version:"3.5"services:rabbitmq:container_name:rabbitmqimage:rabbitmq:3.9.15-management-alpinerestart:alwaysenvironment:-TZ=Asia/Shanghai-RABBITMQ_DEFAULT_USER=admin#设置Rabb......
  • 基于SpringBoot+Vue的影视剧评论系统 ---附源码 78088
    目  录摘要Abstract1绪论1.1研究背景与意义1.2国内外研究现状1.3论文结构与章节安排2 影视剧评论系统分析2.1可行性分析2.1.1技术可行性分析2.1.2经济可行性分析2.1.3法律可行性分析2.2系统功能分析2.2.1功能性分析2.3系统用例分析......
  • 英飞凌—TC397芯片详解(1)
    写在前面本系列文章主要讲解英飞凌TC397芯片的相关知识,希望能帮助更多的同学认识和了解英飞凌TC397芯片。若有相关问题,欢迎评论沟通,共同进步。(*^▽^*)1.介绍英飞凌的AURIX系列的MCU在市场上的应用比较多,尤其是在汽车电子行业广泛应用。以下是对TC397的简单介绍:6个CPU......
  • vue打包优化——使用webpack-parallel-uglify-plugin并行压缩JavaScript
    1、安装插件npminstallwebpack-parallel-uglify-plugin--save-dev我用的install命令,其他命令大同小异,大家百一下就行2、配置vue.config.js首先引入插件:constParallelUglifyPlugin=require('webpack-parallel-uglify-plugin');这里注意我用的vue-cli构建的项目,所以修改w......
  • SQL Server全方位指南:从入门到高级详解
    本文将分为三大部分,逐步深入SQLServer的基础知识、进阶技巧和高级特性,旨在帮助从初学者到经验丰富的开发人员深入理解和使用SQLServer。一、入门篇1.1什么是SQLServer?SQLServer是由微软开发的关系型数据库管理系统(RDBMS),广泛应用于企业应用程序和数据分析领域。它提......
  • Vue 3中的setup()函数的作用是什么?
    Vue3引入了CompositionAPI,这是一种新的组件编写方式,旨在提供更好的逻辑复用和代码组织。setup()函数是CompositionAPI的入口点,它在组件实例创建之前被调用,并且是响应式系统的上下文。本文将介绍setup()函数的作用,并使用Vue3的setup语法糖提供示例代码。setup()......
  • Python 单元测试详解:Unittest 框架的应用与最佳实践
    Python单元测试详解:Unittest框架的应用与最佳实践文章目录Python单元测试详解:Unittest框架的应用与最佳实践一什么是Unittest1不使用Unittest测试框架2使用Unittest测试框架二unittest使用建议1先写测试case后写测试逻辑2测试文件以_test.py结尾......
  • Python 异常控制详解:try-except 的应用与多种异常处理策略
    Python异常控制详解:try-except的应用与多种异常处理策略文章目录Python异常控制详解:try-except的应用与多种异常处理策略一可遇见的异常二处理多个异常1多个异常一起处理2多个异常分开处理三try-except-else四try-except-finally五raise手动抛出异常六Pyt......
  • Go语言并发编程之Channels详解
    并发编程是Go语言的一大特色,而channel(通道)则是Go语言中用于实现并发的核心工具之一。它源于CSP(CommunicatingSequentialProcesses)的概念,旨在让多个goroutine之间能够高效地进行通信和同步。本文将深入探讨channel的用法、原理和最佳实践,通过丰富的示例代码和详细的解释,帮......