浅谈Vue中监听属性—watch监听器的使用方法

目录

💡 监听属性的概念

💡 watch有什么作用

💡 watch的基本语法

💡 监听属性的优缺点

💡 使用watch的场景


💡 监听属性的概念

在计算机科学中,watch是一种调试技术,用于监视程序运行时特定变量的值。当程序在调试器控制下执行时,调试器会显示变量的当前值,并在程序执行过程中自动更新该值。

在Vue中,watch 是一种用于监测数据变化并做出回应的技术。watch 可以监听任何一个数据属性,并在该属性发生变化时执行指定的函数。


💡 watch有什么作用

watch 可以监听数据的变化,并在数据变化时执行所指定的回调函数。它可以做以下几件事情:

✔ 监听数据变化:watch 可以监听 Vue 实例上的任何数据变化,包括简单数据类型、对象、数组和计算属性等。

✔ 接收新旧值:当数据发生变化时,watch 回调函数会接受到两个参数,分别是新值和旧值,这可以方便我们比较数据变化,进一步做出相应的处理。

✔ 执行响应函数:watch 的主要作用就是执行我们所指定的响应函数,以便我们对数据变化作出及时的响应,如重新计算、渲染视图或发送网络请求等。

深度监听:watch 还可以通过配置 deep 选项来深度监听嵌套对象的变化,这样当嵌套对象中的属性发生变化时也能捕获到。

立即执行:watch 还可以通过配置 immediate 选项来在初始化组件时立即执行回调函数,而不必等待数据变化。

✔  取消监听:当一个 watch 监听器不再需要时,可以使用 unwatch 方法来取消监听。

综上所述,watch 可以监听数据变化并执行相应操作,这使得我们可以很方便地对数据变化做出处理和重新计算。在实际开发中,watch 经常被用来检测表单输入变化、监听状态变化以及优雅地处理异步操作等。


💡 watch的基本语法

// 对象式写法
watch: {
  // 监听的属性名
  属性名: {
    handler: function (newVal, oldVal) {
      // 对属性变化作出响应
    }
  }
}

// 函数式写法
watch: {
  // 监听的属性名,参数为新旧值
  '属性名'(newVal, oldVal) {
    // 对属性变化作出响应
  }
}

其中,handler 是一个函数,其第一个参数是属性的新值第二个参数是属性的旧值

属性名 是需要监听的属性名称。当属性发生变化时,watch 可以触发指定的响应函数来处理这个变化,比如,重新计算或发送请求等。

watch 可以监听对象、数组、计算属性等数据类型的变化,也可以通过 deep 选项来深度监听嵌套对象的变化,还可以使用 immediate 选项来立即执行回调函数。

通过示例来进一步了解监听属性

示例一:

new Vue({  
  data: {  
    message: 'Hello Vue!'  
  },  
  watch: {  
    // 当 `message` 属性发生变化时,执行 `handleMessageChange` 函数  
    message(newVal, oldVal) {  
      console.log('message changed from', oldVal, 'to', newVal);  
    }  
  },  
  methods: {  
    handleMessageChange(newVal, oldVal) {  
      console.log('message changed from', oldVal, 'to', newVal);  
    }  
  }  
});

在上面的示例中,我们通过watch选项观察了message属性的变化。当message的值发生改变时,回调函数将会被触发,并输出新的值和旧的值。

除了直接在回调函数中执行逻辑外,还可以使用命名函数作为回调函数,或者使用箭头函数。此外,还可以在回调函数中返回一个值,以便在数据变化后执行其他操作。

除了观察数据的变化,watch选项还可以用于观察计算属性或方法。在这种情况下,回调函数将会在计算属性或方法的结果发生变化时被触发。

示例二:

<template>
  <div>
    <p>当前计数:{{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  watch: {
    count(newValue, oldValue) { // 监听 count 变化
      console.log(`count 变化,新值为 ${newValue},旧值为 ${oldValue}`);
    },
  },
  methods: {
    increment() {
      this.count++; // 改变 count 的值
    },
  },
};
</script>

上面的示例中,我们定义了一个 count 数据属性,并使用 watch 监听它的变化。在按钮点击事件中,我们改变了 count 的值,watch 监听到了数据的变化并执行了回调函数,输出了新旧值信息。

还可以通过配置 deep 和 immediate 选项来深度监听和在组件初始化时立即执行回调函数。

<script>
export default {
  data() {
    return {
      person: {
        name: 'Tom',
        age: 18,
      },
    };
  },
  watch: {
    'person.name'(newValue, oldValue) { // 深度监听 person.name 的变化
      console.log(`person.name 变化,新值为 ${newValue},旧值为 ${oldValue}`);
    },
  },
  created() {
    this.$watch('person', (newValue, oldValue) => { // 深度监听 person 对象及其子属性的变化
      console.log('person 变化', newValue, oldValue);
    }, { deep: true });

    this.$watch('person.name', (newValue, oldValue) => { // 初始化时立即执行回调函数
      console.log(`person.name 变化,新值为 ${newValue},旧值为 ${oldValue}`);
    }, { immediate: true });
  },
};
</script>

或是 

<script>
export default {
  data() {
    return {
      person: {
        name: 'Tom',
        age: 18,
      },
    };
  },
  watch: {
    'person.name':{
        handler(newValue, oldValue) { // 深度监听 person.name 的变化
        console.log(`person.name 变化,新值为 ${newValue},旧值为 ${oldValue}`);
        },

        // 当要监听对象/对象某个属性或数组、数组元素的时候需要添加deep:true属性
        deep: true; // 深度监听 person 对象及其子属性的变化

        // 如果想在第一次绑定的时候执行此监听函数 则需要设置immediate属性
        immediate: true; // 初始化时立即执行回调函数
  },
};
</script>

在这里,我们使用 watch 深度监听了 person.name 的变化,并在创建组件时使用 $watch 方法深度监听 person 对象的变化,同时设置了 immediate 选项,在初始化时立即执行回调函数。

参考:watch事件监听三种用法-CSDN博客 | watch监听事件的多种用法-ViewDesign

番外:vue - 组件中watch:{}监听与 this.$watch()的区别


💡 监听属性的优缺点

优点:

响应式:watch 可以实现数据的响应式监测,即在数据变化时自动执行回调函数,方便及时地对变化做出处理。

灵活性:watch 可以监听任意数据属性,并执行自定义的回调函数,使得我们可以根据具体需求做出相应的操作。

深度监听:watch 可以通过配置 deep 选项来深度监听嵌套对象的变化,不仅监听父级对象的变化,还能捕获到子级对象属性的变化。

初始化执行:watch 可以通过配置 immediate 选项在组件初始化时立即执行回调函数,而不必等待数据变化。

取消监听:当一个 watch 不再需要时,可以通过 unwatch 方法来取消监听,避免不必要的资源消耗。

缺点:

异步问题:watch 回调函数是异步执行的,在一些特定场景下,可能无法立即获取到最新的数据。如果需要立即获取到最新数据,可能需要配合 $nextTick 或使用计算属性来解决。

频繁触发:如果被监听的数据频繁变化,可能会导致 watch 回调函数被频繁触发,影响性能。此时,可以通过配置 immediate 选项和优化逻辑来减少不必要的回调触发。

复杂性:当使用多个 watch 监听多个数据时,可能会导致代码复杂度增加,维护起来稍显困难。在这种情况下,可以考虑使用计算属性来代替 watch。

那我们该怎么样去处理这些缺点呢?

✔ 处理异步问题:可以使用 $nextTick 方法来确保在更新视图之后再执行回调函数,以获取最新的数据。

watch: {
  count: {
    handler(newValue, oldValue) {
      this.$nextTick(() => {
        console.log(`count 变化,新值为 ${newValue},旧值为 ${oldValue}`);
        // 在这里进行相应的操作
      });
    },
    immediate: true,
  },
}

✔ 优化频繁触发:如果被监听的数据频繁变化,可以考虑通过设置 immediate 选项或优化逻辑来减少不必要的回调触发。例如,可以使用 debounce 或 throttle 函数来限制回调函数的执行频率,以避免过多的触发。

✔ 简化复杂性:当使用多个 watch 监听多个数据时,可以考虑使用计算属性来代替 watch。计算属性具有自动的依赖跟踪和缓存机制,能够简化代码并提高性能。

computed: {
  countInfo() {
    return `当前计数:${this.count}`;
  },
},
watch: {
  countInfo(newValue, oldValue) {
    console.log(`countInfo 变化,新值为 ${newValue},旧值为 ${oldValue}`);
  },
},

这样,通过计算属性 countInfo 来监听 count 的变化,代码会更加清晰和易于维护。

综上所述,watch 提供了一种方便而强大的数据监测技术,但需要注意处理异步问题和频繁触发的情况,以及根据实际场景选择最佳的数据监听方式。


💡 使用watch的场景

数据监听:当数据发生变化时,可以使用 watch 来监听数据的变化,并在变化时执行相应的操作。例如,监听表单字段的变化,当表单字段发生变化时,可以根据新的值进行实时的验证、计算或发送请求等操作。

异步操作:当需要监听异步操作的结果或状态时,可以使用 watch 来监视异步操作的变化。例如,监视网络请求的结果,当请求返回时,可以根据返回的数据更新组件的状态或进行后续操作。

路由变化:当路由发生变化时,例如切换页面或参数变化,可以使用 watch 监听 $route 对象的变化,并根据新的路由信息进行相应的页面更新或数据加载操作。| Vue中监听路由参数变化的几种方式

深度监听对象或数组:当需要深度监听对象或数组内部属性的变化时,可以使用 watch 来进行深度监听。例如,监听一个复杂的数据结构,当其中某个属性发生变化时,可以触发相应的操作。

状态管理:当使用状态管理工具(如 Vuex)时,可以使用 watch 来监听状态的变化,并根据状态的变化进行相应的处理。例如,监听某个状态的变化,在状态变化时更新视图或触发其他操作。

总而言之,watch 适用于需要监听数据变化并执行相应操作的场景,特别是在需要处理异步操作、深度监听对象或数组、响应路由变化等情况下。

使用watch还需要注意的几个点:

1. 主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,可以看作是 computed 和 methods 的结合体;

2. 可以监听的数据来源:data,props,computed内的数据;

3. watch支持异步;

4. 不支持缓存,监听的数据改变,直接会触发相应的操作;

5. 监听函数有两个参数,第一个参数是最新的值,第二个参数是输入之前的值,顺序一定是新值,旧值。


☀ 参考资料

vue2中watch(侦听器)讲解以及解决深度监听新值和旧值相同的两种方案(手写深拷贝和JSON.parse())

watch事件监听三种用法 | vue中watch如何对对象进行深度监听 | watch监听事件的多种用法

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【SQL】SQL语法小结

相关资料 参考链接1&#xff1a;SQL 语法&#xff08;超级详细&#xff09; 参考链接2&#xff1a;史上超强最常用SQL语句大全 SQL练习网站&#xff1a;CSDN、牛客、LeetCode、LintCode SQL相关视频&#xff1a; 推荐书籍&#xff1a; 文章目录 数据分析对SQL的要求SQL语法简介…

onlyoffice源码编译

环境准备 官网要求CPU dual core 2 GHz or better RAM at least 2 GB, but depends of the host OS. More is better HDD at least 40 GB of free space SWAP at least 4 GB, but depends of the host OS. More is better SoftwareOS 64-bit Ubuntu 16.04 The solution has be…

ARM day1

一、概念 ARM可以工作的七种模式用户、系统、快中断、中断、管理、终止、未定义ARM核的寄存器个数 37个32位长的寄存器&#xff0c;当前处理器的模式决定着哪组寄存器可操作&#xff0c;且任何模式都可以存取&#xff1a; PC(program counter程序计数器) CPSR(current program…

QT上位机开发(dock窗口在软件布局中的应用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在软件开发中&#xff0c;一般有主窗口和子窗口之分。主窗口也就是main window&#xff0c;是最重要的操作界面。子窗口就是各种属性配置、参数配置…

USB8814动态信号采集卡——声音振动类信号处理的理想之选!

背景介绍&#xff1a; 科技的发展在一定程度上依赖于对信号的处理&#xff0c;信号处理技术的先进性在很大程度上决定了科技发展的速度和方向。数字信号处理技术的崛起&#xff0c;彻底改变了传统的信息与信号处理方式&#xff0c;使得数据采集这一前期工作在数字系统中发挥着…

使用PyTorch实现混合专家(MoE)模型

Mixtral 8x7B 的推出在开放 AI 领域引发了广泛关注&#xff0c;特别是混合专家&#xff08;Mixture-of-Experts&#xff1a;MoEs&#xff09;这一概念被大家所认知。混合专家(MoE)概念是协作智能的象征&#xff0c;体现了“整体大于部分之和”的说法。MoE模型汇集了各种专家模型…

网页设计(六)表格与表格页面布局

一、设计《TF43: 前端的发展与未来》日程表 《TF43: 前端的发展与未来》日程表 文字素材&#xff1a; 前端是互联网技术的重要一环&#xff0c;自上世纪80年代万维网技术创立以来&#xff0c;Web成就了大量成功的商业公司&#xff0c;也诞生了诸多优秀的技术解决方案。因其标…

SDRAM小项目——命令解析模块

简单介绍&#xff1a; 在FPGA中实现命令解析模块&#xff0c;命令解析模块的用来把pc端传入FPGA中的数据分解为所需要的数据和触发命令&#xff0c;虽然代码不多&#xff0c;但是却十分重要。 SDRAM的整体结构如下&#xff0c;可以看出&#xff0c;命令解析模块cmd_decode负责…

网络分层及三次握手

5-网络 数据传输 服务器如何响应 网络分层和概念 2个地址&#xff1a;ip:逻辑地址&#xff1b;mac物理地址 通信过程中链路会发生转换&#xff0c;但是网络层寻址是不变的 ip地址不变&#xff0c;mac会变 每层的协议 每层协议指的就是约定和规范 应用层&#xff1a;cdn&dns…

QT第五天

使用QT绘图和绘图事件&#xff0c;完成仪表盘绘图&#xff0c;如下图&#xff1a; 程序运行结果&#xff1a; 代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPainter> #include <QPen> #include <QBrush&…

React初探:从环境搭建到Hooks应用全解析

React初探&#xff1a;从环境搭建到Hooks应用全解析 一、React介绍 1、React是什么 React是由Facebook开发的一款用于构建用户界面的JavaScript库。它主要用于构建单页面应用中的UI组件&#xff0c;通过组件化的方式让开发者能够更轻松地构建可维护且高效的用户界面。 Reac…

ubuntu qt 运行命令行

文章目录 1.C实现2.python实现 1.C实现 下面是封装好的C头文件&#xff0c;直接调用run_cmd_fun()即可。 #ifndef GET_CMD_H #define GET_CMD_H#endif // GET_CMD_H #include <iostream> #include<QString> using namespace std;//system("gnome-terminal -…

LaTeX系列6——表格

\documentclass[UTF-8]{ctexart} \begin{document} \begin{tabular}{|c|c|c|} \hline 单元格1&单元格2&单元格3\\ \hline 单元格4&单元格5&单元格6\\ \hline 单元格7&单元格8&单元格9\\ \hline \end{tabular} \end{document} 1.表格里面的信息要放在 \…

芯品荟 | 电脑机箱键盘副屏市场调研报告

一.产品简介 1.带TFT彩屏电脑机箱 2.带小TFT彩屏电脑键盘 为什么电脑机箱&键盘&#xff0c;要带屏&#xff1f; 带屏的电脑机箱&键盘客户群体? 电竞玩家、设计师、电子发烧友、股民...... 二、市场规模 中国电脑机箱年产量约6000万台&#xff0c;键盘年产量约3亿…

一文掌握SpringBoot注解之@Async知识文集(1)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

用LED数码显示器伪静态显示数字1234

#include<reg51.h> // 包含51单片机寄存器定义的头文件 void delay(void) //延时函数&#xff0c;延时约0.6毫秒 { unsigned char i; for(i0;i<200;i) ; } void main(void) { while(1) //无限循环 { P20xfe; …

介绍下Redis?Redis有哪些数据类型?

一、Redis介绍 Redis全称&#xff08;Remote Dictionary Server&#xff09;本质上是一个Key-Value类型的内存数据库&#xff0c;整个数据库统统加载在内存当中进行操作&#xff0c;定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作&#xff0c;Redis的性…

Android 布局菜鸟 android中的布局类型和特点?

一、LinearLayout(线性布局) 1、 特点: 主要以水平或垂直方式来排列界面中的控件。并将控件排列到一条直线上。在线性布局中,如果水平排列,垂直方向上只能放一个控件,如果垂直排列,水平方向上也只能放一个控件。 2、适⽤场景: Android开发中最常见的 ⼀种布局⽅式,排列…

基于若依的ruoyi-nbcio系统调用代码生成表的注意问题

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/n…

图像分类 | 基于 Labelme 数据集和 VGG16 预训练模型实现迁移学习

Hi&#xff0c;大家好&#xff0c;我是源于花海。本文主要使用数据标注工具 Labelme 对自行车&#xff08;bike&#xff09;和摩托车&#xff08;motorcycle&#xff09;这两种训练样本进行标注&#xff0c;使用预训练模型 VGG16 作为卷积基&#xff0c;并在其之上添加了全连接…