请不要在 Vue 中滥用“watch”功能,拜托了!

news2024/12/23 6:14:05

随着 Vue 3Composition API 风格的普及,使用 watch 的成本越来越低。

现在,我们可以在任何地方使用 watch 来监听响应式数据。随着业务的推进,你可能会在代码中看到大量的 watch

当你接手修改这些充满 watch 代码时,我相信你心里肯定会感到非常困惑和无奈。

真实案例剖析

让我们来看一个真实的代码案例:

在上面的示例中, dataListtemplate 中进行渲染。

props.id 初始化或者更新时, dataList 将进行更新

props.disableListprops.type 更新时,又会触发 dataList的更新

上述的过程可以简化成下面的流程图:

我们猛地一看,好像并没有什么大问题,但是当我们几个月之后回来再改这段代码的时候,就会发现这里面的问题了

我们以 dataList 变量为例,追根溯源来理清这个组件的业务逻辑。

在上述示例代码中, dataList 的数据更新会和多个数据的变化相关,

首先,它通过 props.id 上的 watch 从服务器异步更新。

然后,它通过 props.disableListprops.type 上的 watch 同步更新。

如果有新的需求需要更新 dataList 的逻辑,在更新之前,我们必须要理清楚更新的逻辑,这样才能避免改动引发。

但是事实却是相反,在我们实践编写代码中,特别是当维护别人的代码(尤其是复杂的代码)时,我们通常不喜欢修改现有的代码,而是在上面添加自己的代码。

更改别人的复杂代码可能会触发改动引发,因此,我们通常最保险的做法是添加另一个 watch 并在那里实现 dataList 的最新业务逻辑:

但是这样操作的话,经过几次迭代后,这个 vue 文件变得混乱,充满了许多 watch 语句,导致了“屎山代码”。

当然,这种代码的编写过程也被视为 “防御性编程”

解决方案

看到前面示例的缺点后,静下心思考一下🤔, 到底可维护的代码应该是什么样的?

在我看来,它应该看起来像这样:

dataListtemplate 中渲染,然后同步更新 dataList ,最后从服务器异步获取 dataList

整个过程可以可视化为单个线程。现在我们可以尝试进行优化上面的示例。

首先我们梳理一下,代码中 dataList同步变更异步变更

我们无法更改异步变更,因为从业务角度来看, props.id 更新后,就必须要从后端获取新的 dataList

但是我们可以将同步变更中的所有代码堆叠到 computed 中。优化后的代码如下:

template 中,我们不再渲染 dataList 变量,而是渲染 renderDataListrenderDataList 是一个 computed ,其中包含 dataList 的所有同步相关逻辑。代码逻辑流程图如下:

现在 dataList 相关的业务逻辑现在已经变成了线性序列

故我们可以做如下调整:

小结

我们在正常的业务代码编写中,应该避免同步和异步更新都乱写在 watch 中,否则后续维护 dataList变量的相关逻辑就会非常痛苦。

到时候,watch 到处更新 dataList 值,你完全理不清楚这个值到底因为什么变化而变化。

所以我们在日常编码的时候,就应该将数据的来源区分成同步变更 还是 异步变更。, 多使用 computed 计算属性,尽量避免使用 watch监听器

如果对你有帮助的话,欢迎点赞👍、关注➕、转发

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

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

相关文章

电梯修理升级,安装【电梯节能】能量回馈设备

电梯修理升级,安装【电梯节能】能量回馈设备 1、节能率评估 15%—45% 2、降低机房环境温度,改善电梯控制系统的运行环境; 3、延长电梯使用寿命; 4、机房可以不需要使用空调等散热设备的耗电,间接节省电能。 欢迎私询哦…

使用PID算法实现DAC模拟量输出的快速调节

目录 概述 1 系统框架和算法 1.1 框架结构介绍 1.2 PID算法实现 1.2.1 理论介绍 1.2.2 离散化位置式PID 1.2.3 位置式PID算法 2 STM32Cube 配置项目 2.1 配置参数 2.2 GENERATE项目 3 功能实现 3.1 ADC采样数据功能 3.2 DAC数据转换 3.3 PID相关的调制函数 4 …

黄子韬vs徐艺洋卫生间风波

【热搜爆点】黄子韬VS徐艺洋:卫生间风波背后的职场与友情界限探讨在这个充满欢笑与意外的综艺时代,《跟我出游吧》再次以它独有的魅力,引爆了一个既尴尬又引人深思的话题——“黄子韬要上徐艺洋的卫生间?”这不仅仅是一句简单的调…

CSS|03 尺寸样式属性文本与字体属性

尺寸样式属性 height:元素高度height的值:auto 自动length 使用px定义高度% 基于包含它的块级对象的百分比高度 width:元素的宽度width的值与height一样span标签可以设置宽度、高度吗? 答:不可以,因为span标签是一个行…

mysql-sql-第十四周

学习目标: sql 学习内容: 40.查询学过「哈哈」老师授课的同学的信息 Select * from students left join score on students.stunmscore.stunm where counm (select counm from teacher left join course on teacher.teanmcourse.teanm where teache…

DCU整体硬件架构

DCU整体硬件架构 DCU整体硬件架构 首先,DCU通过PCI-E总线与CPU处理器相连,它是CPU主机系统的一个硬件扩展,其存在的目的是为了对程序某些模块或者函数进行加速。虽然DCU是原硬件系统的一个扩展,接受CPU调度指挥,但是在…

西部智慧健身小程序+华为运动健康服务

1、 应用介绍 西部智慧健身小程序为用户提供一站式全流程科学健身综合服务。用户通过登录微信小程序,可享用健康筛查、运动风险评估、体质检测评估、运动处方推送、个人运动数据监控与评估等公益服务。 2、 体验介绍西部智慧健身小程序华为运动健康服务核心体验如…

认识流式处理框架Apache Flink

目录 一、Apache Flink 的基础概念 1.1 Apache Flink是什么? 1.2 Flink的定义 二、Apache Flink 的发展史 2.1 Flink前身Stratosphere 2.2 Flink发展时间线及重大变更 三、Flink核心特性 3.1 批流一体化 3.2 同时支持高吞吐、低延迟、高性能 3.3 支持事件时…

前端接入chatgpt,实现流式文字的显示

前端接入chatgpt,实现流式文字的显示 业务需求: 项目需要接入chatgpt提供的api,后端返回流式的字符,前端接收并实时显示。 相关技术原理: 1. JS中的Stream流: 在JavaScript中,使用Stream流通常指的是处理数据流的…

react native中使用@react-navigation/native进行自定义头部

react native中使用react-navigation/native进行自定义头部 效果示例图实例代码 效果示例图 实例代码 /* eslint-disable react-native/no-inline-styles */ /* eslint-disable react/no-unstable-nested-components */ import React, { useLayoutEffect } from react; import…

ripro子主题eeesucai-child集成后台美化包(适用于设计素材站+资源下载站等)

模板介绍 最新RiPro子主题模板,Eeesucai-child模板后台美化包,使用该子主题前需要安装WordPress程序和RiPro模板。 安装教程 第一种,在wordpress后台上传主题,上传之后点启动 第二种,上传到wordpress主题目录/wp-con…

MatLab 二维图像绘制基础

MatLab 二维图像绘制基础 plot 描点绘图 %% % 二维绘图 ,plot进行描点,步长越小,越平滑 x [1:9]; y [0.1:0.2:1.7]; X x y*i; % 复数 plot(X)plot绘制矩阵 %% % 当X Y 为矩阵时,对应矩阵中的元素依次绘制 t 0:0.01:2*pi; …

将多个Excel工作表合并成一个工作表,1分钟轻松搞定!

1. 案例展示 2. 视频详解 多个工作表合并成一个工作表 3. 图文详解 第一步:相同格式(表头)的表格,并将所有表格都放在一个文件夹内“将多个工作表合并成一个工作表”(自己定义文件名) 第二步:新…

Linux 【线程池】【单例模式】【读者写者问题】

💓博主CSDN主页:麻辣韭菜💓   ⏩专栏分类:Linux初窥门径⏪   🚚代码仓库:Linux代码练习🚚   🌹关注我🫵带你学习更多Linux知识   🔝 目录 🏳️‍🌈前言 …

VSCode打开其它IDE项目注释显示乱码的解决方法

问题描述:VSCode打开Visual Studio(或其它IDE)工程,注释乱码,如下图所示: 解决方法:点击VSCode右下角的UTF-8,根据提示点击“通过编码重新打开”,再选择GB2312&#xff0…

JDBC链接kerberos认证的impala数据库报错问题解决

先上代码 public static Connection connectToImpala() {try {log.info("ketTabPath:" ketTabPath);log.info("krb5Path:" krb5Path);System.setProperty("java.security.krb5.conf", krb5Path);System.setProperty("sun.security.krb5.…

python如何输出list

直接输出list_a中的元素三种方法: list_a [1,2,3,313,1] 第一种 for i in range(len(list_a)):print(list_a[i]) 1 2 3 313 1 第二种 for i in list_a:print(i) 1 2 3 313 1 第三种,使用enumerate输出list_a方法: for i,j in enum…

线程池666666

1. 作用 线程池内部维护了多个工作线程,每个工作线程都会去任务队列中拿取任务并执行,当执行完一个任务后不是马上销毁,而是继续保留执行其它任务。显然,线程池提高了多线程的复用率,减少了创建和销毁线程的时间。 2…

【FFmpeg】avformat_find_stream_info函数

【FFmpeg】avformat_find_stream_info 1.avformat_find_stream_info1.1 初始化解析器(av_parser_init)1.2 查找探测解码器(find_probe_decoder)1.3 尝试打开解码器(avcodec_open2)1.4 读取帧(re…

Redis的使用(二)redis的命令总结

1.概述 这一小节,我们主要来研究一下redis的五大类型的基本使用,数据类型如下: redis我们接下来看一看这八种类型的基本使用。我们可以在redis的官网查询这些命令:Commands | Docs,同时我们也可以用help 数据类型查看命令的帮助文档。 2. 常…