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

news2024/11/15 21:55:47
官方解释:

> 观察 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.msg
                setTimeout(() => {
                    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.coloradmin.cn/o/1698302.html

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

相关文章

细粒度图像分类论文(AAM模型方法)阅读笔记

细粒度图像分类论文阅读笔记 摘要Abstract1. 用于细粒度图像分类的聚合注意力模块1.1 文献摘要1.2 研究背景1.3 本文创新点1.4 计算机视觉中的注意力机制1.5 模型方法1.5.1 聚合注意力模块1.5.2 通道注意力模块通道注意力代码实现 1.5.3 空间注意力模块空间注意力代码实现 1.5.…

VScode解决报错“Remote-SSH XHR failed无法访问远程服务器“的方案

VScode解决报错"Remote-SSH XHR failed无法访问远程服务器"的方案 $ ls ~/.vscode-server/bin 2ccd690cbff1569e4a83d7c43d45101f817401dc稳定版下载链接&#xff1a;https://update.code.visualstudio.com/commit:COMMIT_ID/server-linux-x64/stable 内测版下载链接…

ABAQUS应用07-实现拉伸和压缩刚度不同的弹簧建模

文章目录 0、背景描述1、步骤 0、背景描述 到目前为止&#xff0c;本文的内容我还没有具体实践过&#xff0c;但是个人认为后期是会用到的。比如说&#xff0c;对于风电机组地基转动刚度的设置&#xff0c;土体就是一种拉压刚度并不相同的材料。所以现在先记录下来&#xff0c…

如何利用OpenHarmony ArkUI的Canvas组件实现涂鸦功能?

简介 ArkUI是一套UI开发框架&#xff0c;提供了开发者进行应用UI开发时所需具备的能力。随着OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;不断更新迭代&#xff0c;ArkUI也提供了很多新的组件&#xff0c;例如Canvas、OffscreenCanvas、XComponent组…

Git Large File Storage (LFS) 的安装与使用

Git Large File Storage [LFS] 的安装与使用 1. An open source Git extension for versioning large files2. Installing on Linux using packagecloud3. Getting StartedReferences 1. An open source Git extension for versioning large files https://git-lfs.com/ Git …

手把手从0到1教你做STM32+FreeRTOS智能家居--第10篇之ASR-PRO语音识别模块

前言 先看实验效果&#xff0c;通过ASR-PRO语音智能识别控制模块&#xff0c;来控制STM32单片机实现对应的控制功能。因为后台好多小伙伴私信问用的是什么语音模块&#xff0c;并且很少在网上看到如何使用此模块相关的文章&#xff0c;所以我将会在本篇文章详细介绍一下此模块…

列表和元组

2.1序列概述 列表和元组的主要不同在于&#xff0c;列表是可以修改的&#xff0c;而元组不可以。这意味着列表适用于需 要中途添加元素的情形&#xff0c;而元组适用于出于某种考虑需要禁止修改序列的情形。 Python支持一种数据结构的基本概念&#xff0c;名为容器&#xff0…

Gradle筑基——Gradle Maven仓库管理

基础概念&#xff1a; 1.POM pom:全名Project Object Model 项目对象模型&#xff0c;用来描述当前maven项目发布模块的基础信息 pom主要节点信息如下&#xff1a; 配置描述举例&#xff08;com.android.tools.build:gradle:4.1.1&#xff09;groupId组织 / 公司的名称com.…

clone方法总结Java

Java中Object类当中有许多方法&#xff0c;如图所示&#xff1a; clone方法就是其中一种&#xff0c;分为浅拷贝&#xff0c;深拷贝举一个例子&#xff1a; 浅拷贝&#xff1a; 在Person类当中右键鼠标然后&#xff0c;选中Generate&#xff1a; 然后重写clone方法 protecte…

福昕PDF编辑器自定义快捷方式

你是否为用不惯福昕PDF编辑器自带的快捷键而发愁&#xff1f;今天&#xff0c;我和大家分享一下如何设置自己想要的快捷键方式&#xff0c;希望能对大家有帮助。 步骤一&#xff1a;打开福昕PDF编辑&#xff0c;并找到更多命令 步骤二&#xff1a;切换到键盘一栏&#xff0c;并…

微信小程序基础 --模板语法(4)

模板语法 1、wxml视图结构 1.1 概述 开发文档&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/code.html#WXML-%E6%A8%A1%E6%9D%BF 从事过网页编程的人知道&#xff0c;网页编程采用的是 HTML CSS JS 这样的组合&#xff0c;其中 HT…

【热门话题】Debian常用命令指南

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Debian常用命令指南引言1. 文件与目录操作lscdmkdirrmcpmv 2. 包管理aptdpkg 3.…

WSL安装CentOS系统

1.首选找一个linux系统&#xff0c;执行docker命令 docker run -it --rm centos:7 bash 2.开一个新窗口&#xff0c;将系统导出 docker export e0ee25406703 -o centos.tar 3.切换到wsl命令&#xff0c;导入tar包 wsl --import centos D:\wsl\centos D:\wsl\centos.tar cen…

FFmpeg+QT播放器实战1---UI页面的设计

1、播放器整体布局的设计 该部分使用QT的UI工具&#xff0c;进行整体页面设置&#xff0c;如下图1所示&#xff1a; 2、控制布局的设计 创建ctrBar的UI页面并进行页面布局设置&#xff0c;如下图2所示&#xff1a; 将图1中ctrBarWind对象提升为ctrBar类(该界面替代原先的控…

简单好用的文本识别方法--付费的好用,免费的更有性价比-记笔记

文章目录 先说付费的进入真题&#xff0c;免费的来喏&#xff01;PixPin微信 先说付费的 直达网址!!! 进入真题&#xff0c;免费的来喏&#xff01; PixPin 商店里就有 使用示例&#xff1a; 可以看到&#xff1a;贴在桌面上的图片可以复制图片中的文字&#xff0c;真的很…

香橙派AIpro使用SSH远程登录

香橙派AIpro可以连接HDMI显示器使用&#xff0c;也可以远程登录。这里采用MobaXterm软件远程登录开发板。 首先要使得控制电脑和香橙派开发板连接到同一个局域网&#xff0c;两者的IP地址能够ping通。在Windows 下可以使用MobaXterm 远程登录开发板&#xff0c;首先新建一个ss…

Imperva 导致的ORAbase 乱码

DBCA Failing Because Of Garbage Characters In ORACLE_BASE Variable (Doc ID 2947963.1)​编辑To Bottom In this Document Symptoms Changes Cause Solution APPLIES TO: Oracle Database Configuration Assistant - Version 19.14.0.0.0 and later Oracle Database - E…

分享活动规划

前两天去参加菁英学院的一些辅导&#xff0c;是关于苏州久富农业机械的发展&#xff0c;看了他们企业的故事&#xff0c;我觉得我们农机很有前景和发展空间&#xff0c;我希望重新经过一次分享活动来分享我的感触&#xff0c;希望能够再次把我学到的内容传输到其他班的同学们 请…

软件需求规范说明模板

每个软件开发组织都会为自己的项目选用一个或多个标准的软件需求规范说明模板。有许多软件需求规范说明模板可以使用(例如ISO/IEC/IEEE2011;Robertson and Robertson2013)。如果你的组织要处理各种类型或规模的项目&#xff0c;例如新的大型系统开发或是对现有系统进行微调&…

「YashanDB迁移体验官」Mysql生产环境迁移至YashanDB数据库深度体验

「YashanDB迁移体验官」Mysql生产环境迁移至YashanDB数据库深度体验 1. 前言1.1 产品介绍1.2 产品架构1.3 产品规格1.3.1 数据库版本支持1.3.2 数据类型支持 2. YMP安装2.1 环境说明2.2 执行安装2.3 访问YMP2.3.1 YMP登录界面2.3.2 YMP迁移流程 3. YMP数据迁移3.1 创建数据源3.…