第十三节:带你梳理Vue2 : watch侦听器

官方解释:> 观察 Vue 实例变化的一个表达式或计算属性函数。回调函数得到的参数为新值和旧值。表达式只接受监督的键路径。对于更复杂的表达式,用一个函数取代<br/>## 1.  侦听器的基本使用侦听器可以监听data对象属性或者计算属性的变化watch是观察属性的变化所以watch的属性名必须要与观察人的名字保持一致;只要观察的值发生了变化才会触发,```html
<div id="app"><!-- 监听器 --><input type="text" v-model="msg">
</div><script>   const vm = new Vue({el: "#app",data: {msg:""},watch:{msg(){console.log("数据发生了变化")console.log(arguments)}}})
</script>

通过这个理解,我们就会发现, 只要数据一但发生变化,那么监听函数msg就会被触发, 监听函数中接受两个参数,第一个参数是数据变化后的新值, 第二个参数是数据变化后的旧值


尽管大部分时间我们用不到侦听器, 但侦听器对于处理异步操作非常适合,

例如我们需要将用户输入的内容延迟5秒后现在在页面上

<div id="app"><!-- 监听器 --><input type="text" v-model="msg">{{showMsg}}
</div><script>   const vm = new Vue({el: "#app",data: {msg:"",showMsg: ""},watch:{msg(){let newValue = this.msgsetTimeout(() => {this.showMsg = newValue},5000)}}})
</script>

2. 获取旧值

侦听器在数据发生变化的时候就会触发,触发时,数据已经更新,我们那到就是新值,那么我们如何获取之前的旧值呢

其实当监听的属性发生变化时,侦听器会被传入两个参数

第一个参数:侦听器所监听属性的当前值,即更新后的值

第二个参数: 原来旧值

<div id="app"><!-- 监听器 --><input type="text" v-model="msg">
</div><script>   const vm = new Vue({el: "#app",data: {msg:"",},watch:{msg(val, oldval){console.log(val);console.log(oldval);            }}})
</script>

3. 监听data对象中某个对象的属性

data属性中的数据值除了是基本数据类型的数据外,还有可能是对象类型,那么我们如何监听对象数据的属性的

<div id="app"><!-- 监听器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"苹果",price: 20},},watch:{fruit(val, oldval){console.log(val);console.log(oldval);            }}})
</script>

如果我们按照之前的监听方式, 那么我们就会发现,当我们修改fruit属性值的时候,侦听器不会被触发, 侦听器会在fruit对象整体被修改时触发.


为了监听对象里某个特定属性的变化,可以在侦听器的名称中使用.操作符, 就像访问这个对象的属性

<div id="app"><!-- 监听器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"苹果",price: 20},},watch:{"fruit.price"(val, oldval){console.log(val);console.log(oldval);            }}})
</script>

4. 深度监听

通过上面的例子,我们知道,我们可以监听对象的特定属性的变化,可以我们想监听整个对象的所有属性的变化就需要给对象所有的属性添加监听就不是特别的好,如果我们只是单纯的监听对象,那么属性的变化并不会触发监听器,只有整个对象被替换时才会触发

所以我们可以通过deep属性来开启对象的深度监听,

4.1 deep 选项

为了发现对象内部值的变化,可以在选项参数中指定 deep: true。注意监听数组的变更不需要这么做。

如果需要开启深度监听,那么监听器将不再是一个函数,而需要写成一个对象,对象中配置deep属性

<div id="app"><!-- 监听器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"苹果",price: 20},},watch:{fruit:{// 此时fruite 就是一个配置对象,里面的属性都是配置选项// handler 就是原来的监听函数, 当数据变化是执行的函数handler(val,oldval){console.log(val);console.log(oldval);            },// 深度监听选项deep:true}}})
</script>

此时我们就做到了即监听这整个对象的变化, 也简体对象里面所有的属性的变化,


4.2 immediate选项

监听除了deep选项外,还有immediate选项

指定 immediate: true 将立即以表达式的当前值触发回调,

watch:{fruit:{// 此时fruite 就是一个配置对象,里面的属性都是配置选项// handler 就是原来的监听函数, 当数据变化是执行的函数handler(val,oldval){console.log(val);console.log(oldval);            },// 深度监听选项deep:true,immediate: true  // 理解执行监听函数handler}
}

5. 引用类型深度监听后,属性变化,获取新旧值问题

但是细心的朋友就会发现我们在改变对象属性的时候,虽然触发了侦听器,但是我没发获取旧值了,我们拿到的两个形参的值都是对象更改后的新值.

出于某种原因没有深入过滤对象的每个属性,那么只能监听到对象的变化,而JavaScript里对象的赋值是引用赋值,虽然属性变化了,但是它引用的地址却一直没有变化,这样的话,当对象的属性值改变了,Vue虽然知道它改变了,但也只能循着引用地址去获得对象,可此时对象的属性的值已经改变了,因此Vue并不能得到变异之前的值。

示例:

<div id="app"><!-- 监听器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"苹果",price: 20},},watch:{fruit:{handler(val,oldval){console.log(11)console.log(val);console.log(oldval);            },deep:true}},})
</script>

此时当数据发生变化是, 查看handler 两个参数值

监听属性.png


5.1 解决方案: 利用计算属性

官方方案: 观察 Vue 实例变化的一个表达式或计算属性函数。回调函数得到的参数为新值和旧值。表达式只接受监督的键路径。对于更复杂的表达式,用一个函数取代


既然 watch无法在变异对象或数组时监听新旧值,那么我们可以先使用JSON.parse()来浅复制一遍data对象,然后在复制的对象上修改,完了重新赋值给该data对象,这样变化前后两个对象是完全不一样的,因为它们的引用地址完全不一样,Vue可以循着两个引用地址获得新旧两个

<div id="app"><!-- 监听器 --><input type="text" v-model.number="fruit.price"></div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"苹果",price: 20},},watch:{fruitNew:{handler(val,oldval){console.log(11)console.log(val);console.log(oldval);            },deep:true}},computed:{fruitNew(){return JSON.parse(JSON.stringify(this.fruit));}},})
</script>

6. 可以通过Vue是实例对象的$watch属性来监听

除了 watch 选项之外,您还可以使用命令式的 vm.$watch ,通过Vue实例对象来监听数据


6.1 普通监听

可以通过实例对象调用$watch设置监听

<!-- 监听字符变化-->
<div id="app"><!-- 监听器 --><input type="text" v-model="msg"></div><script>   const vm = new Vue({el: "#app",data: {msg:'你好'}})// $watch 是一个实例方法vm.$watch("msg",(val,newVal) => {console.log(val)console.log(newVal);       })
</script>

6.2 监听配置

<div id="app"><!-- 监听器 --><input type="text" v-model.number="fruit.price">
</div><script>   const vm = new Vue({el: "#app",data: {fruit:{name:"苹果",price: 20`在这里插入代码片`},}})// $watch 是一个实例方法vm.$watch("fruit",(val,newVal) => {console.log(val)console.log(newVal);       },{deep: true})
</script>

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

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

相关文章

现代C++ 如何使用 Lambda 使代码更具表现力、更容易理解?

使用 Lambda 使代码更具表现力 一、Lambda VS. 仿函数二、总结 一、Lambda VS. 仿函数 Lambda 是 C11 中最引人注目的语言特性之一。它是一个强大的工具&#xff0c;但必须正确使用才能使代码更具表现力&#xff0c;而不是更难理解。 首先&#xff0c;要明确的是&#xff0c;…

向npm发布自己写的vue组件,使用vite创建项目

向npm发布自己写的vue组件&#xff0c;使用vite创建项目 创建项目 pnpm create vite输入项目名称 由于我的组件是基于 ant-design-vue和vue的&#xff0c;需要解析.vue文件&#xff0c;我又安装了下面4个。 然后执行 pnpm i安装依赖 vite.config.ts import { defineC…

防范TOCTOU竞态条件攻击

防范TOCTOU竞态条件攻击 在软件开发过程中&#xff0c;我们常常会遇到需要在使用资源之前检查其状态的情况。然而&#xff0c;如果资源的状态在检查和使用之间发生了变化&#xff0c;那么检查的结果可能会失效&#xff0c;导致软件在资源处于非正常状态时执行无效操作。这种时…

[datawhale202405]从零手搓大模型实战:TinyAgent

结论速递 TinyAgent项目实现了一个简单的Agent智能体&#xff0c;主要是实现了ReAct策略&#xff08;推理调用工具的能力&#xff09;&#xff0c;及封装了一个Tool。 项目实现有一定的疏漏。为了正确运行代码&#xff0c;本次对代码Agent部分进行了简单修改&#xff08;完善…

windows安装rocketmq

1.下载连接 https://rocketmq.apache.org/download/ 2.解压到D盘下&#xff08;其他位置也可以&#xff09; 3.配置环境变量 需要有jdk环境 新建ROCKETMQ_HOME&#xff0c;刚刚解压的位置 编辑Path&#xff0c;新增%ROCKETMQ_HOME%\bin 4.启动mqnameserver 进入安装bin目录下…

交叉编译——

什么是交叉编译 交叉编译 是在一个平台上生成临海一个平台可执行代码. eg.在windows上面编写C51代码&#xff0c;并编译生成可执行代码。如xx.hex 我们在Ubuntu上编写树莓派的代码&#xff0c;并编译成可执行代码。a.out. 是在树莓派上运行&#xff0c;不在Ubuntu Linux上面运…

便携式iv测试仪特点

TH-PV30便携式IV测试仪是一种用于测量半导体器件电学特性的设备&#xff0c;它具有体积小、重量轻、便于携带等特点&#xff0c;广泛应用于半导体行业、科研实验室以及教育领域。 该测试仪的工作原理基于四探针法&#xff0c;通过在半导体器件表面放置四个金属探针&#xff0c…

【vs2022】安装copilot和reshaper

直接安装新版vs 17.10 自带集成的copilot支持安装resharper 可以跳过市场里的reshper安装好后依然可以直接使用vs。 resharper 2024.1.2 市场里还是i老版本&#xff1a; copilot 不兼容,这个是之前市场安装的版本 官方建议用vs intall 安装 安裝 GitHub Copilot GitHub.Co…

详解http协议

什么是HTTP协议 定义 Http协议即超文本传送协议 (HTTP-Hypertext transfer protocol) 。 它定义了浏览器&#xff08;即万维网客户进程&#xff09;怎样向万维网服务器请求万维网文档&#xff0c;以及服务器怎样把文档传送给浏览器。从层次的角度看&#xff0c;HTTP是面向&am…

第四十一天 | 62.不同路径 63.不同路径|| 343.整数拆分 96.不同的二叉搜索树

题目&#xff1a;62.不同路径 1.二维dp数组dp[i][j]含义&#xff1a;到达&#xff08;i&#xff0c;j&#xff09;位置有dp[i][j]种方法。 2.动态转移方程&#xff1a;dp[i][j] dp[i - 1][j] dp[i][j - 1] 3.初始化&#xff1a;dp[0][j] 1, dp[i][0] 1 &#xff08;第一…

uniapp 安卓 Pc端真机浏览器调试

下载插件:真机模拟浏览器 1. 安装, 每次启用时使用usb 线连接电脑, 并且打开手机或者POS (调试设备)开发者模式, 比如我的是pos 机 则在系统设置中找到版本号,点击多次就会触发开发者模式 2.打开真机模拟软件,打开后会打开一个浏览器,如果想要模拟google的浏览器则 在浏览器地…

精准键位提示,键盘盲打轻松入门

在说明精准键位提示之前&#xff0c;我们先来看一张图&#xff1a; 这是一张标准的基准键位图&#xff0c;也就是打字时我们双手的8个手指放在基准键位上&#xff0c;在打不同的字母时&#xff0c;我们的手指以基准键位为中心&#xff0c;或上、或下、或左、或右&#xff0c;在…

《拯救大学生课设不挂科第二期之Windows11下安装VC6.0(VC++6.0)与跑通Hello,World!程序教程》【官方笔记】

背景与目标人群&#xff1a; 大学第一次学C语言的时候&#xff0c;大部分老师会选择VC6这个编辑器。 但由于很多人是新手&#xff0c;第一次上大学学C语言。 老师要求VC6.0&#xff08;VC6.0&#xff09;写C语言跑程序可能很多人还是第一次接触电脑。 需要安装VC6这个编辑器…

Docker常用软件安装

文章目录 1.安装Tomcat1.docker hub查找镜像并复制拉取镜像命令2.拉取镜像到本地1.执行官网命令2.查看是否拉取成功 3.启动tomcat4.退出和重启1.由于是以交互方式启动的&#xff0c;所以不方便&#xff0c;直接ctrl c退出2.查看当前的容器3.使用docker start 命令启动容器&…

【cocos creator 】生成六边形地图

想要生成一个六边形组成的地图 完整代码示例 以下是完整的代码示例&#xff0c;包含了注释来解释每一步&#xff1a; cc.Class({extends: cc.Component,properties: {hexPrefab: {default: null,type: cc.Prefab},mapWidth: 10, // 网格的宽度&#xff08;六边形的数量&am…

【Flutter】线性布局弹性布局层叠布局

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Flutter学习 &#x1f320; 首发时间&#xff1a;2024年5月25日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e; 目…

4、PHP的xml注入漏洞(xxe)

青少年ctf&#xff1a;PHP的XXE 1、打开网页是一个PHP版本页面 2、CTRLf搜索xml&#xff0c;发现2.8.0版本&#xff0c;含有xml漏洞 3、bp抓包 4、使用代码出发bug GET /simplexml_load_string.php HTTP/1.1 补充&#xff1a; <?xml version"1.0" encoding&quo…

内网穿透--Nps-自定义-上线

免责声明:本文仅做技术交流与学习... 目录 Nps项目: 一图通解: 1-下载nps/npc 2-服务端启动 访问web网页: 添加客户端&#xff0c;生成密匙. 3-kali客户端连接服务端 4-添加协议隧道. 5-kali生成后门&#xff1a; 6-kali创建监听: Nps项目: https://github.com/ehang…

蓝桥杯Web开发【模拟题一】15届

1.动态的Tab栏 日常在使用移动端 APP 或访问 PC 端网站的时候&#xff0c;常常发现在一些有工具栏或者 Tab 栏的页面会有顶栏固定的效果。简单来说&#xff0c;在页面未开始滚动时顶栏处在其原有的位置上&#xff0c;当页面向下滚动一定区域后&#xff0c;顶栏会跟随滚动固定在…

HTTPS证书——网站如何实现HTTPS访问?

实现网站HTTPS访问可以简化为以下四个基本步骤&#xff0c;确保过程既通俗易懂又条理清晰&#xff1a; 1. 申请SSL证书 - 目的&#xff1a;SSL证书是实现HTTPS加密的关键&#xff0c;它验证了网站的身份&#xff0c;并提供了加密数据所需的密钥。 - 操作&#xff1a;首先&…