Vue 响应式监听 Watch 最佳实践

image.png

一. 前言

上一篇文章我们学习了 watch 的基础知识,了解了它的基本使用方法及注意事项,本篇文章我们继续了解在Vue 中 响应式监听 watch 的妙用。了解 watch 的基础使用请参考上一篇文章:

详解 Vue 中 Watch 的使用方法及注意事项icon-default.png?t=O83Ahttps://blog.csdn.net/qq_24956515/article/details/142452530

通过了解,我们知道了 watch 是 Vue 中的是一个强大的功能,可以让我们监听数据的变化并在变化发生时执行相应的操作。在开发 Vue 应用过程中,watch可以帮助我们处理许多实际的应用场景,并实现最佳实践。

在本文中,我们将会深入探讨watch的实际使用场景,并总结最佳实践,以下的场景都是我在实际项目中能够总结的经常使用的,包括但不限于以下内容:

  1. 表单验证:用来监听表单输入框的变化,并对输入的内容进行验证。

  2. 异步操作:用于监听数据的变化,并触发相应的异步操作,比如网络请求等。

  3. 联动操作:监听数据的变化,并在变化时执行相应的联动操作。

  4. 计算属性与watch的结合使用:比较watch和计算属性的区别,以及它们在不同场景下的应用和最佳实践。

  5. 同步多个watch:处理多个watch同时触发的情况,并提供一些同步多个watch的最佳实践建议。

  6. 监听路由参数:使用watch来监听 Vue 路由参数的变化,并根据参数的变化来更新组件的状态或执行相应的操作。

通过详细了解实际使用场景和最佳实践,可以帮助我们更好地理解和运用 Vue 的watch功能,从而提高 Vue 应用的编码灵活性。

二. watch 的实际应用场景

1. 表单验证

Vue 的watch选项在表单验证中有广泛的应用。通过监听表单字段的变化,可以实时检查用户的输入并进行验证。下面是一个简单的示例,展示了如何使用watch实现表单验证:

<template><div><input v-model="username" placeholder="请输入用户名" /><p v-if="usernameError" class="error">用户名不能为空</p><input v-model="password" type="password" placeholder="请输入密码" /><p v-if="passwordError" class="error">密码不能为空</p><button @click="submitForm" :disabled="isInvalid">提交</button></div>
</template><script>
export default {data() {return {username: "",password: "",usernameError: false,passwordError: false,};},watch: {username(value) {this.validateUsername(value);},password(value) {this.validatePassword(value);},},methods: {validateUsername(username) {this.usernameError = username.length === 0;},validatePassword(password) {this.passwordError = password.length === 0;},submitForm() {if (!this.isInvalid) {// 验证通过,提交表单// ...}},},computed: {isInvalid() {return this.usernameError || this.passwordError;},},
};
</script><style>
.error {color: red;
}
</style>

在上述示例中,我们使用了两个watch来监听usernamepassword字段的变化。当用户输入用户名时,会触发username字段的watch回调函数,并调用validateUsername方法进行验证。同理,当用户输入密码时,会触发password字段的watch回调函数,并调用validatePassword方法进行验证。通过设置usernameErrorpasswordError变量来控制错误提示的显示。

submitForm方法中,我们通过isInvalid计算属性来判断表单是否通过验证。只有当isInvalid的值为false时,才允许提交表单。

这样,每当用户输入用户名或密码时,watch会自动调用相应的验证方法,实时检查用户的输入。当用户名或密码为空时,会显示相应的错误提示,如果表单通过了验证,提交按钮就可以点击。

这个示例只是表单验证中的一种简单情况,实际应用中可能会涉及更复杂的验证逻辑。通过使用watch选项,我们可以根据具体需求来构建强大的表单验证功能。

2. 异步操作

Vue 的watch属性可以用于监听数据的变化,并触发相应的异步操作。以下是一个简单的 Vue 异步操作的代码示例:

<template><div><input v-model="inputValue" placeholder="请输入内容" /><div v-if="loading">加载中...</div><div v-else>{{ result }}</div></div>
</template><script>export default {data() {return {inputValue: "",loading: false,result: "",};},watch: {inputValue(newInputValue) {this.loading = true;// 模拟异步操作,比如发送请求setTimeout(() => {// 异步操作完成后更新数据this.loading = false;this.result = this.processData(newInputValue);}, 2000);},},methods: {processData(input) {// 这里可以进行对输入数据的处理return "处理后的结果: " + input;},},};
</script>

在上述代码示例中,我们使用v-model指令将输入框的值与 Vue 实例的inputValue属性进行绑定。然后,通过watch属性监听inputValue的变化,并在变化时触发异步操作。

watch的回调函数中,我们首先将loading设置为true以显示加载中的提示信息。然后,我们模拟了一个异步操作,比如发送请求。在异步操作完成后,我们将loading设置为false,并更新result的值,这个值会根据异步操作的结果而改变。

在这个示例中,我们模拟了一个 2 秒钟的异步操作,处理了输入的数据,并将处理后的结果赋给result。在异步操作进行中,用户会看到"加载中..."的提示信息,当异步操作完成后,会显示处理后的结果。

通过以上的代码示例,我们可以看到 Vue 的watch属性在异步操作中的实际应用。它可以方便我们监听数据的变化,并在变化发生后执行异步操作,从而实现了异步操作的控制与处理。

3. 联动操作

Vue 的watch属性可以用于监听数据的变化,并在变化时执行相应的联动操作。以下是一个简单的 Vue 联动操作的代码示例:

<template><div><input v-model="inputValue" placeholder="请输入内容" /><div><h3>输入内容的长度:</h3><p>{{ inputLength }}</p></div></div>
</template><script>export default {data() {return {inputValue: "",inputLength: 0,};},watch: {inputValue(newInputValue) {// 在输入值变化时更新输入内容的长度this.inputLength = newInputValue.length;},},};
</script>

在这个代码示例中,我们使用v-model指令将输入框的值与 Vue 实例的inputValue属性进行双向绑定。然后,通过watch属性监听inputValue的变化,在变化时更新inputLength的值。

watch的回调函数中,我们将输入值的新值作为参数(newInputValue)传入,并根据新值的长度更新inputLength的值。

在这个示例中,每当用户在输入框中输入内容时,watch会监听到inputValue的变化,并更新inputLength的值,以反映输入内容的长度。

通过以上的代码示例,我们可以看到 Vue 的watch属性在联动操作中的实际应用。它可以方便地监听数据的变化,并执行相应的操作,用于实现多个数据之间的联动效果。例如,在这个示例中,我们实现了输入内容长度与输入值之间的联动,保持了它们的同步更新。

4. 同步多个监听

在 Vue 中,可以使用watch来监听多个数据的变化并进行相应的处理。这种情况下,我们通常称之为同步多个watch

有一个常见场景是表单联动,当表单中的多个字段之间存在关联关系时,可以使用多个watch来实现表单的联动效果。例如,当选择某个选项时,其他选项的可选项列表会相应改变。

<template><div><select-model="selectedCategory"><option value="fruit">水果</option><option value="vegetable">蔬菜</option></select><select v-model="selectedItem"><option v-for="item in items" :key="item.id">{{ item.name }}</option></select></div>
</template><script>
export default {data() {return {selectedCategory: null,selectedItem: null,items: []};},watch: {selectedCategory(newCategory) {// 根据选定的类别获取对应的选项列表this.items = this.fetchItemsByCategory(newCategory);// 重置选中的选项this.selectedItem = null;},selectedItem(newItem) {// 处理选中的选项this.handleSelectedItem(newItem);}},methods: {fetchItemsByCategory(category) {// 根据类别获取对应的选项列表// 在实际项目中,请替换为真正的异步请求// 返回选项列表return [];},handleSelectedItem(item) {// 处理选中的选项// ...}}
};
</script>

在上述示例中,我们使用了两个watch来监听selectedCategoryselectedItem两个数据的变化。当选择的类别Category改变时,第一个watch会重新获取对应类别的选项列表,并重置selectedItem为 null。而当选中的选项selectedItem改变时,第二个watch会执行相应的逻辑处理。

5. 动态路由的处理

Vue 的watch属性在处理动态路由方面也有实际应用场景。比如:路由发生变化时,watch会监听到$route的变化,并执行相应的操作,主要用于处理新的路由信息。以下是一个简单的 Vue 动态路由处理的代码示例:

<template><div><router-view></router-view></div>
</template><script>export default {watch: {$route(newRoute, oldRoute) {// 在路由变化时执行相应的操作console.log("路由变化:", newRoute, oldRoute);// 根据新的路由信息执行其他逻辑this.handleRouteChange(newRoute);},},methods: {handleRouteChange(route) {// 根据路由信息进行处理// 此处仅打印新的路由路径作为示例console.log("新的路由路径:", route.path);},},};
</script>

在这个代码示例中,我们有一个基本的 Vue 组件,使用了 Vue Router 进行路由管理。我们通过<router-view>标签来渲染当前的路由组件。

通过watch属性,我们可以监听 Vue Router 中的$route对象,它包含了当前路由的信息。在$route对象发生变化时,watch回调函数会被触发。

在这个示例中,我们监听了$route,并在路由变化时执行相应的操作。在回调函数中,我们可以获取到新的路由信息(newRoute)和旧的路由信息(oldRoute),并可以根据路由信息执行其他逻辑。

handleRouteChange方法中,我们根据路由信息进行处理。在这个示例中,我们简单地使用console.log来打印新的路由路径。

每当路由发生变化时,watch会监听到$route的变化,并执行相应的操作,比如处理新的路由信息。

通过以上的代码示例,我们可以看到 Vue 的watch属性在动态路由处理方面的实际应用。它可以方便地监听路由的变化,并执行相应的操作,用于处理动态路由相关的逻辑。

三. watch 的最佳实践

Vue 的watch是一个非常有用的功能,它提供了对 Vue 实例的属性或者表达式的侦听器。这个侦听器会在属性或者表达式的值发生变化时触发相应的回调函数。

以下是一些 Vue 中使用watch的最佳实践:

1. 减少回调函数中的复杂逻辑

回调函数应该尽量简洁,遵循单一责任原则。如果需要处理复杂的逻辑,可以将逻辑拆分为单独的方法,然后在回调函数中调用这些方法。

2. 合理使用深度监听

默认情况下,watch是浅监听的,只能监听到对象的引用变化。如果需要监听对象内部的属性变化,可以通过deep选项进行深度监听。

watch: {obj: {handler(newVal, oldVal) {// 对象内部属性的变化},deep: true}
}

watch选项虽然提供了深度监听的功能,可以跟踪嵌套对象或数组的变化。但在使用深度监听时,需要注意以下几点:

  • 性能问题:深度监听会在对象或数组的每个级别都进行递归遍历,因此在嵌套层级较深、数据量较大的情况下,可能会带来性能问题。

  • 深度监听和计算属性:深度监听和计算属性之间存在一些互相影响的问题。由于深度监听会触发对象或数组的所有变化,可能导致计算属性的计算次数过多,从而影响性能。在使用深度监听时,要特别关注计算属性的计算逻辑,以避免不必要的计算。

  • 对象和数组的变化检测:Vue 的响应式系统可以检测到对象或数组的变化,并触发相应的更新。但对于某些特定情况,如直接使用通过索引直接修改数组元素、直接用下标设置对象属性等,Vue 可能无法检测到变化。

  • 引用类型数据的变化:深度监听只能监听引用类型的变化,无法检测到引用类型数据内部属性的变化。例如,对于对象的属性值的变化,Vue 会自动进行侦测和响应。但如果仅修改了属性值,而未修改整个对象的引用,深度监听将无法触发。

深度监听是一种强大的功能,可以用于监听嵌套对象或数组的变化,但在使用时需要注意性能、计算属性、变化检测和引用类型数据的影响。根据具体的场景和需求,灵活地选择使用深度监听或其他替代方案。

3. 避免循环依赖

watch中的依赖关系是自动解析的,但是要注意避免出现循环依赖的情况。当在 watch 选项中监听属性时,如果在回调函数中修改了被监听的属性,可能会导致循环引用的问题。为了避免这种问题,可以在修改属性前检查新旧值是否相等,或者使用 Vue 的this.$nextTick()来推迟执行。

4. 使用immediate选项

immediate选项可以在组件加载时立即执行回调函数一次。这常用于初始化数据或者处理一些需要立即执行的操作。

watch: {foo: {handler(newVal, oldVal) {// 回调函数},immediate: true}
}

5. 使用 watch 配合 computed

computed属性可以根据数据的变化自动更新计算结果,而watch可以用于监听数据的变化并执行相应的副作用操作。可以结合使用这两个功能来实现更复杂的逻辑。

watch: {fullName: {handler(newVal, oldVal) {// 监听computed属性fullName的变化},immediate: true}
},
computed: {fullName() {return this.firstName + ' ' + this.lastName;}
}

6. 合理使用watch

watch 选项可以用于在数据变化时执行一些复杂的逻辑操作,但过度使用 watch 可能会导致性能问题。在不必要的情况下,可以尝试使用计算属性来替代 watch。只在需要监听特定数据变化时使用 watch

因此,虽然 watch虽然是一个强大的功能,但是在不必要的情况下,应该尽量避免过多的使用。因为每个watch都需要消耗一些性能,当watch过多或者逻辑复杂时,可能会导致性能下降。优先考虑使用computed属性来处理需求。

7. 注意异步更新的情况

在 Vue 中,watch选项默认是同步的,即在侦听到数据变化后立即触发回调函数。但有时候我们需要在watch中进行异步操作,例如发送网络请求或执行定时任务等。下面介两种实现异步更新的方法:

  • 使用nextTick方法:可以在watch回调函数中使用$nextTick方法,将操作放入下一次 DOM 更新循环中执行,从而实现异步更新。

watch: {username(newValue) {this.$nextTick(() => {// 异步操作// ...});}
}

this.$nextTick方法接受一个回调函数作为参数,并在下一次 DOM 更新循环中执行该回调函数。这样就可以将需要异步执行的操作放在回调函数内部。

  • 使用setTimeout方法:可以在watch调函数中使用setTimeout方法来延迟执行代码,实现异步更新。

watch: {username(newValue) {setTimeout(() => {// 异步操作// ...}, 0);}
}

通过将代码放入setTimeout回调函数内部,可以以 0 毫秒的延迟将代码放入事件队列中从而实现异步执行。

注意:使用异步更新会使得代码的执行顺序发生变化,可能会导致一些意想不到的问题。确保在异步操作中正确处理所有依赖关系和数据同步,避免出现竞争条件或数据不一致的情况。

另外,对于复杂的异步操作,推荐使用Promiseasync/await等异步编程的方式,以便更好地管理和处理异步逻辑。

总结:虽然watch默认是同步的,但可以通过$nextTicksetTimeout等方式实现异步更新。根据具体需求选择适合的方式来处理异步操作,确保代码的正确性和可维护性。

综上所述,合理使用 Vue 的 watch 选项可以方便地监听数据变化并执行相应的操作。但需要注意避免过度使用、处理循环引用和使用相应的选项来适应不同的需求。

通过遵循以上的最佳实践,可以更好地应用 Vue 的watch功能,提高代码的可读性、可维护性,同时避免潜在的性能问题。

四. 总结

在本篇文章中,我们详细探讨了 Vue 的watch功能的实际使用场景和最佳实践。了解和熟练运用 watch 可以帮助我们更好地处理数据变化和执行相应的操作,提高 Vue 应用的质量和效率。

在使用watch时,我们应该根据具体的需求和场景进行设计和实践,合理选择选项和处理方式。同时,我们了解到异步处理、与计算属性配合使用以及监听路由参数的方法和技巧。

通过遵循最佳实践,我们可以编写更具可读性、可维护性和性能的代码。在实际开发中,不断学习和掌握 watch 功能的用法,加深对 Vue 的理解,将有助于我们构建出更优雅、高效的 Vue 应用。

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

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

相关文章

ARM单片机的中断详细过程(重要)

ARM单片机的中断详细过程&#xff08;重要&#xff09; 一、ARM异常中断 ARM的异常&#xff08;中断源&#xff09;总共分为三类&#xff08;八种&#xff09;&#xff1a; 三类&#xff1a; &#xff08;1&#xff09;执行指令引起的直接异常&#xff1a;软件中断&#xff…

0920作业+思维导图

一、 写一个shell脚本&#xff0c;将以下内容放到脚本中&#xff1a; 在家目录下创建目录文件&#xff0c;dirdir下创建dir1和dir2把当前目录下的所有文件拷贝到dir1中&#xff0c;把当前目录下的所有脚本文件拷贝到dir2中把dir2打包并压缩为dir2.tar.xz再把dir2.tar.xz移动到…

13.第二阶段x86游戏实战2-动态模块地址

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

LabVIEW项目编码器选择

在LabVIEW项目中&#xff0c;选择增量式&#xff08;Incremental Encoder&#xff09;和绝对式&#xff08;Absolute Encoder&#xff09;编码器取决于项目的具体需求。增量式编码器和绝对式编码器在工作原理、应用场景、精度和成本等方面存在显著差异。以下从多方面详细阐述两…

MySql数据库---单表查询,高级查询,外键约束,多表关系,建表原则

思维导图 模糊查询 select * from 表名 where 列名 like 匹配符; 符号: _ 表示一个任意字符 符号: % 表示0或者多个任意字符 # &#xff08;1&#xff09;查询商品名称含有"香"字的所有商品信息&#xff1b; select * from product where pname like %香%; # &#x…

【车联网安全】车端知识调研

一、CAN总线&#xff1a; 1、定义&#xff1a; CAN 总线相当于汽车的神经网络&#xff0c;连接车内各控制系统,其通信采用广播机制&#xff0c;各连接部件均可收发控制消息&#xff0c;通信效率高&#xff0c;可确保通信实时性。当前市场上的汽车至少拥有一个CAN网络&#xff0…

Thinkphp(TP)

1.远程命令执行 /index.php?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]system&vars[1][]whoami 2.远程代码执行 /index.php?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]phpinfo&vars[1][]…

多模态文档编辑器flowmix/docx,9月更新复盘!

嗨, 大家好, 我是徐小夕. 之前一直在社区分享零代码&低代码的技术实践&#xff0c;也陆陆续续设计并开发了多款可视化搭建产品&#xff0c;比如&#xff1a; H5-Dooring&#xff08;页面可视化搭建平台&#xff09;V6.Dooring&#xff08;可视化大屏搭建平台&#xff09;橙…

js发送邮件至指定邮箱功能实现方式和技巧?

js发送邮件至指定邮箱的教程&#xff1f;怎么使用Node.js发信&#xff1f; 无论是用户反馈、订单确认还是密码重置&#xff0c;js发送邮件至指定邮箱的需求无处不在。AokSend将深入探讨js发送邮件至指定邮箱的实现方式和技巧&#xff0c;帮助开发者更好地理解和应用这一功能。…

html TAB、table生成

1. 代码 <!DOCTYPE html> <head> <meta charset"UTF-8"> <title>Dynamic Tabs with Table Data</title> <style> /* 简单的样式 */ .tab-content { display: none; border: 10px solid #ccc; padding: 30px; mar…

道路车辆功能安全 ISO 26262标准(3)—概念阶段

写在前面 本系列文章主要讲解道路车辆功能安全ISO26262标准的相关知识&#xff0c;希望能帮助更多的同学认识和了解功能安全标准。 若有相关问题&#xff0c;欢迎评论沟通&#xff0c;共同进步。(*^▽^*) 1. 道路车辆功能安全ISO 26262标准 3. ISO 26262-3 概念阶段 我们来…

浙江欧瑞雅装饰材料有限公司:全屋定制,为爱家增添无限温馨!

浙江欧瑞雅装饰材料有限公司&#xff1a;全屋定制&#xff0c;为爱家增添无限温馨&#xff01;在追求生活品质与个性化的今天&#xff0c;家已不仅仅是一个居住的空间&#xff0c;更是情感的寄托和个性的展现。浙江欧瑞雅装饰材料有限公司&#xff0c;以其专业的全屋定制服务&a…

论文阅读 - SWATTING Spambots: Real-time Detection of Malicious Bots on X

https://web.archive.org/web/20240523035749id_/https://dl.acm.org/doi/pdf/10.1145/3589335.3651564 目录 ABSTRACT INTRODUCTION METHODOLOGY 3 RESULTS ABSTRACT 在 X&#xff08;前身为 Twitter&#xff09;等社交网络平台上&#xff0c;垃圾邮件机器人的活动日益…

html中为div添加展开与收起功能(div折叠)

1、添加样式 <style type"text/css">.mask {position: absolute;bottom: -5px;color: #4b83f0;font-weight: 700;font-size: 14px;text-align: center;height: 80px;left: 0;right: 0;background-image: -webkit-gradient(linear, left top, left bottom, from…

机械零件检测系统源码分享

机械零件检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

零基础入门AI大模型应用开发——第三天:使用python实现问答机器人

一、简介 问答机器人是一种能够理解用户提问并提供相关答案的程序。它可以用于各种场景&#xff0c;如客户支持、在线教育、信息检索等。用户通过自然语言输入问题&#xff0c;机器人则通过分析问题并检索相关信息来提供回答。 使用什么技术实现的&#xff1f; 自然语言处理&…

电源设计的艺术:从底层逻辑到工程实践

在电子工程的世界里&#xff0c;电源设计是核心中的核心。它不仅是电子设备的能量源泉&#xff0c;更是整个系统稳定运行的基石。随着科技的不断进步&#xff0c;电源设计的要求也越来越高&#xff0c;从效率、稳定性到体积、成本&#xff0c;每一个维度都是工程师们不断追求的…

Github 2024-09-21Rust开源项目日报 Top10

根据Github Trendings的统计,今日(2024-09-21统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Move项目1JavaScript项目1Deno: 现代JavaScript和TypeScript运行时 创建周期:2118 天开发语言:Rust, JavaScript协议类型:MIT Lic…

LSI SAS 9361-8i和SAS3008 12 gb / s PCIe 3.0 RAID 阵列卡配置

LSI SAS 9361-8i和SAS3008 12 gb / s PCIe 3.0 RAID 阵列卡配置 开机&#xff0c;BIOS自检&#xff0c;可以看到设备硬盘信息&#xff0c;以及提示CtrlR进入Raid卡配置界面。 按CtrlR进入Raid卡配置界面&#xff0c;一般来说使用CtrlR进入Raid卡配置界面的Raid卡配置都通用。 …

ant design vue实现表格序号递增展示~

1、代码实例 //current当前页数 //pageSize每页记录数 const columns [{title: 序号,width: 100,customRender: ({ index }) > ${index (current.value - 1) * pageSize.value 1},align: center,fixed: left,} ] 2、效果图