20240628每日前端---------解决vue项目滥用watch

news2024/11/24 17:44:33

主题

滥用watch。

名字解释

watch

例子

先看一个代码例子:

<template>
  {{ dataList }}
</template>

<script setup lang="ts">
import { ref, watch } from "vue";

const dataList = ref([]);
const props = defineProps(["disableList", "type", "id"]);
watch(
  () => props.disableList,
  () => {
    // The logic based on disableList is very complex, and it computes a new list synchronously
    const newList = getListFromDisabledList(dataList.value);
    dataList.value = newList;
  },
  { deep: true }
);
watch(
  () => props.type,
  () => {
    // The logic based on type is very complex and computes a new list synchronously
    const newList = getListFromType(dataList.value);
    dataList.value = newList;
  }
);
watch(
  () => props.id,
  () => {
    // Fetch dataList from the server
    fetchDataList();
  },
  { immediate: true }
);
</script>

在上面的示例中,当props.id被更新或者初始化时候,dataList会从服务器异步获取。

当disableList,type更新时,将同步计算新的 dataList。

代码逻辑流程图如下:
在这里插入图片描述
乍一看,上面的代码似乎很好,但是当不熟悉这个模块的新同事接手时,问题就出现了。

通常,在接管我们不熟悉的业务领域时,我们需要找到一个起点。

对于前端方面哈,这个起点肯定是浏览器中呈现的页面。

在 Vue 中,页面是从模板渲染的,因此识别模板中使用的变量及其来源可以帮助我们理解业务逻辑。

以变量disableList为例,追溯其来源通常可以明确业务逻辑。

在我们的例子中,来源是多种多样的,且来自多个来源。

首先,它通过 watch props.id 从服务器异步更新。
然后,它通过监听watch props.disableList 和 watch props.type 上实现同步更新。

此时,不熟悉业务的同事收到产品要求以更新检索逻辑时,必须首先熟悉其多个来源背后的逻辑。

在了解了逻辑之后,他们需要准确分析哪些应该修改以满足产品要求。

然而,在实践中,在维护别人的代码(尤其是复杂代码)时,我们通常不愿意修改现有代码,而是在上面添加我们自己的代码。

更改别人的复杂代码可能会引入错误,然后我们可能会受到指责。因此,我们通常的方法是添加另一个并实现最新的业务逻辑:

watch(
  () => props.xxx,
  () => {
    // Add the latest business logic
    const newList = getListFromXxx(dataList.value);
    dataList.value = newList;
  }
);

经过几次迭代后,此文件变得杂乱无章,充斥着大量语句,从而导致“屎山代码”。当然,在某些情况下,这种编码风格可能是故意确保自己在团队中的地位,因为没有人敢碰这个复杂的代码块。。。。。。。

如何解决问题 computer

首先我们先明白正确的可维护的变量流程
在这里插入图片描述
dataList在模板中,同步更新,数据异步从服务器获取。

整个过程可以可视化为单个线程。当新开发人员加入团队迭代相关业务时,只需要了解最新的产品需求是建议在同步阶段还是异步阶段修改代码,然后在对应阶段添加最新的代码即可。

基于以上逻辑,代码简写如下:

<template>
  {{ renderDataList }}
</template><script setup lang="ts">
import { ref, computed, watch } from "vue";const props = defineProps(["disableList", "type", "id"]);
const dataList = ref([]);const renderDataList = computed(() => {
  // Calculate the list based on disableList
  const newDataList = getListFromDisabledList(dataList.value);
  // Calculate the list based on type
  return getListFromType(newDataList);
});watch(
  () => props.id,
  () => {
    // Fetch dataList from the server
    fetchDataList();
  },
  {
    immediate: true,
  }
);
</script>

在上面中,我们不再渲染dataList变量,而是渲染renderDataList变量。 是包含dataList的所有同步相关逻辑的 。代码逻辑流程图如下:
在这里插入图片描述

这样,如果有新需求变量变更,修改逻辑的演示如下:

const renderDataList = computed(() => {
  // Add the latest business logic from the product
  const xxxList = getListFromXxx(dataList.value);
  // Calculate the list based on disableList
  const newDataList = getListFromDisabledList(xxxList);
  // Calculate the list based on type
  return getListFromType(newDataList);
});

结论

本文介绍了两种主要的使用场景:一种是当被监视的值发生变化并需要同步更新要渲染的值时,另一种是当值发生变化并需要从服务器异步获取要渲染的值时。
如果同步和异步更新都不加区别地写在watch中,那么接手的后续维护者会发现梳理相关逻辑非常痛苦。

这是因为到处都在更新值,完全不清楚在哪里添加最新的业务逻辑。
随着时间的流逝,如果代码变成一堆实例,可维护性就会恶化。

我们的优化解决方案是将所有同步更新的代码堆叠到renderDataList

后续维护者只需要决定新业务是否是同步更新,那么他们就应该在dataList中写入新的业务逻辑。

如果是对 renderDataList的异步更新,则应将新的业务逻辑写入 computed中。

题外话

那么vue中 watch 和computer的区别你知道了吗?
1、缓存机制:
computed属性具有缓存机制。只有当其依赖的数据发生变化时,它才会重新计算。如果依赖的数据没有变化,那么它将直接返回之前缓存的结果。这种缓存机制可以提高性能,避免不必要的计算。
watch属性则没有缓存机制。每当它所监听的数据发生变化时,它都会触发相应的操作,不论这个操作是否已经被执行过。
2、异步支持:
computed不支持异步操作。如果computed内部包含异步操作,它将无法正常工作,因为它依赖于同步的响应式依赖。
watch则支持异步操作。在watch的回调函数中,你可以执行任何异步操作,如网络请求等。
3、执行时机:
computed属性在依赖的数据发生变化时才会执行。如果数据没有变化,那么它将不会执行。
watch属性则会在所监听的数据发生变化时立即执行其回调函数。
4、数据类型:
computed主要用于处理复杂的逻辑运算,返回一个新的属性值。它通常用于处理一些需要通过计算得到的数据,如根据购物车中的商品数量和单价计算出总价等。
watch则主要用于监听数据的变化,并在数据变化时执行一些副作用或异步操作。例如,根据用户输入的地址获取并显示地图信息等。
5、参数和返回值:
computed属性通常不需要额外的参数,它直接返回一个新的属性值。同时,它也可以定义一个setter函数来修改它的值。
watch属性则需要两个参数:newVal(新值)和oldVal(旧值)。在watch的回调函数中,你可以使用这两个参数来执行相应的操作。
6、性能:
由于computed具有缓存机制,因此它在处理大量数据或复杂计算时通常具有更好的性能。
watch则没有缓存机制,因此在处理大量数据或频繁变化的数据时可能会导致性能问题。

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

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

相关文章

MySQL高级-SQL优化-insert优化-批量插入-手动提交事务-主键顺序插入

文章目录 1、批量插入1.1、大批量插入数据1.2、启动Linux中的mysql服务1.3、客户端连接到mysql数据库&#xff0c;加上参数 --local-infile1.4、查询当前会话中 local_infile 系统变量的值。1.5、开启从本地文件加载数据到服务器的功能1.6、创建表 tb_user 结构1.7、上传文件到…

笔记本电脑安装CentOS

正文共&#xff1a;1234 字 24 图&#xff0c;预估阅读时间&#xff1a;2 分钟 前面我们对VPP进行了多次介绍&#xff08;羡慕&#xff01;大佬的VPP能达到180G性能&#xff0c;而我的却只有13.5G&#xff09;&#xff0c;可以发现他的很多优点&#xff0c;但是我们也可以发现它…

从源码分析Springboot自动配置原理

一、什么是Springboot的自动配置 Spring Boot自动配置&#xff08;Auto-configuration&#xff09;是Spring Boot框架的核心特性之一&#xff0c;它使得开发者可以更容易地创建基于Spring的应用程序&#xff0c;而无需进行大量的手动配置。自动配置基于开发者添加的jar依赖项来…

Nuxt3 的生命周期和钩子函数(六)

title: Nuxt3 的生命周期和钩子函数&#xff08;六&#xff09; date: 2024/6/30 updated: 2024/6/30 author: cmdragon excerpt: 摘要&#xff1a;本文深入解析了Nuxt3框架中的多个核心生命周期钩子和组件注册功能&#xff0c;包括imports:sources、imports:extend、import…

【Qt】之【Bug】大量出现“未定义的标识符”问题

背景 构建时出现大量错误 原因 中文注释问题 解决 方法1. 报错代码附近的中文注释全部删掉。。。 方法2. 报错的文件添加 // Chinese word comment solution #pragma execution_character_set("utf-8")

2024年【安全生产监管人员】考试资料及安全生产监管人员考试总结

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全生产监管人员考试资料是安全生产模拟考试一点通生成的&#xff0c;安全生产监管人员证模拟考试题库是根据安全生产监管人员最新版教材汇编出安全生产监管人员仿真模拟考试。2024年【安全生产监管人员】考试资料及…

算法力扣刷题 二十六【459.重复的子字符串】

前言 字符串篇&#xff0c;继续。 记录 二十六【459.重复的子字符串】 一、题目阅读 给定一个非空的字符串 s &#xff0c;检查是否可以通过由它的一个子串重复多次构成。 示例 1: 输入: s "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。示例…

录取查询怎么公布?

这篇文章对于教育工作者来说非常有用&#xff0c;提供了关于如何公布学生录取情况的多种方法和注意事项。以下是对您文章的一些补充和建议&#xff1a; 1.易查分的使用&#xff1a;易查分系统是一个很好的工具&#xff0c;特别是对于那些不擅长技术开发的老师。它简化了查询过程…

40 - 餐馆营业额变化增长(高频 SQL 50 题基础版)

40 - 餐馆营业额变化增长 -- 方法一 SELECT t.visited_on,sum(c.amount) amount,ROUND(sum(c.amount) / 7, 2) average_amount FROM customer c,-- 查出足够7天的数据日期(SELECT DISTINCT visited_onFROM customerWHERE visited_on >(SELECT ADDDATE(MIN(visited_on), 6) F…

Nginx-2

一、高级配置 1.1网页状态页 基于nginx 模块 ngx_http_stub_status_module 实现&#xff0c;在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module&#xff0c;否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状…

半个月从几十升粉到500(发红包喽)

目录 1. 背景2. 涨粉秘籍2.1 持续创作高质量内容2.1.1 保持频率2.1.2 技术文章为主2.1.3 图文并茂 2.2 积极参与社区活动2.2.1 社区分享2.2.2 发文活动 2.3 互动与建立信任2.3.1 与读者互动2.3.2 红包互动2.3.3 动态分享 2.4 标题与内容的优化2.4.1 标题吸引2.4.2 内容实用 2.5…

高效办公秘诀:使用Excel超级处理器提高工作效率,提升职场竞争力

在现今快节奏的工作环境中&#xff0c;如何高效地完成工作任务&#xff0c;减少加班时间&#xff0c;成为了许多职场人士关注的焦点。其中&#xff0c;Excel作为一款功能强大的电子表格软件&#xff0c;被广泛应用于数据处理、分析以及报表制作等领域。然而&#xff0c;仅仅依赖…

C++ sizeof的各种

C sizeof的各种 1. 含有虚函数的类对象的空间大小2. 虚拟继承的类对象的空间大小3. 普通变量所占空间大小4. 复合数据类型&#xff08;结构体和类&#xff09;5. 数组6. 类型别名7. 动态分配内存8. 指针9. 静态变量10. 联合体11. 结构体使用#program pack 1. 含有虚函数的类对象…

Linux多进程和多线程(三)进程间通讯-信号处理方式和自定义处理函数

进程间通信之信号 信号信号的种类 信号在操作系统中的定义如下: 信号的处理流程在 Linux 中对信号的处理⽅式 自定义信号处理函数 信号的发送 kill() 函数:raise() 函数: 示例 : 创建⼀个⼦进程&#xff0c;⼦进程通过信号暂停&#xff0c;⽗进程发送 终⽌信号等待信号 pause()…

mysql解压版本安装5.7

1. 官网下载好解压版本 我这边5.7版本 https://dev.mysql.com/downloads/file/?id523570 mysql官网 创建 my.ini文件 内容如下 [client] #客户端设置&#xff0c;即客户端默认的连接参数# socket /data/mysqldata/3306/mysql.sock #用于本地连接的socket套接字 # 默…

Nginx和CDN运用

一.Web缓存代理 1.工作机制 代替客户机向网站请求数据&#xff0c;从而可以隐藏用户的真实IP地址。将获得的网页数据&#xff08;静态Web元素&#xff09;保存到缓存中并发送给客户机&#xff0c;以便下次请求相同的数据时快速响应。 2.代理服务器的概念 代理服务器是一个位…

YOLOv8目标检测在RK3588部署全过程

一&#xff0c;前言 这是一个关于从电脑安装深度学习环境到实现YOLOv8目标检测在RK3588上部署的全过程。 本人配置&#xff1a; 1&#xff0c;一台笔记本 2&#xff0c;一个香橙派5s 二&#xff0c;深度学习环境配置 2.1 安装anaconda 使用清华镜像源下载https://mirror…

内容营销专家刘鑫炜:说真的,我写文章可不是为了流量!

今天&#xff0c;打开某号后台&#xff0c;发现我的号一夜之间加了几十个粉丝&#xff0c;确实有些意外。 说真的&#xff0c;我写文章的目的真不是为了流量。 在这个被大数据和算法统治的时代&#xff0c;我们常常听到这样的声音&#xff1a;“流量就是一切”。然而&#xff…

对原生input加上:当前输入字数/最大输入字数

源码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style>/* 样式…

【解释】i.MX6ULL_IO_电气属性说明

【解释】i.MX6ULL_IO_电气属性说明 文章目录 1 Hyst1.1 迟滞&#xff08;Hysteresis&#xff09;是什么&#xff1f;1.2 GPIO的Hyst. Enable Field 参数1.3 应用场景 2 Pull / Keep Select Field2.1 PUE_0_Keeper — Keeper2.2 PUE_1_Pull — Pull2.3 选择Keeper还是Pull 3 Dr…