第5集丨Vue 江湖 —— 监视属性/侦听属性

目录

  • 一、基本使用
    • 1.1 watch配置监视
    • 1.2 vm.$watch动态监视
    • 1.3 深度监视(deep watch)
    • 1.4 简写形式
  • 二、computed和watch的对比
    • 2.1 使用watch实现setTimeout操作
    • 2.2 用computed无法实现setTimeout
  • 三、其他注意事项
    • 3.1 vue devtools的bug
    • 3.2 @xxx=yyy格式
    • 3.3 将window传入data中

Vue 提供了一种更通用的方式来观察和响应 Vue实例上的数据变动:侦听属性,也成为监视属性

一、基本使用

监视属性watch:

  1. 当被监视的属性变化时,回调函数handler自动调用,进行相关操作。
  2. 监视的属性必须存在,才能进行监视。
  3. 监视的两种写法
    a. new Vue时传入watch配置
    b. 通过vm.$watch来动态实现监视

1.1 watch配置监视

下面案例中,我们通过watch配置属性来给isHuoguo 添加监视,当isHuoguo发生变化时,所配置的handler()函数会调用。

注意:这里有一个属性immediate,其默认值为false。当配置为true时,页面初始化时,让handler调用一下。

<div id="root"><h2>今天我们去吃{{info}}</h2><button @click="change">切换</button>
</div>
<script>const vm = new Vue({el:'#root',data:{isHuoguo:true},computed:{info() {return this.isHuoguo?'火锅':'南京大排档';}},methods: {change() {this.isHuoguo = !this.isHuoguo;}},watch: {isHuoguo:{immediate:true,//默认为false,初始化时,让handler调用一下。handler(newValue, oldValue) {console.log("isHuoguo属性被修改了,newValue:"+newValue+",oldValue:"+oldValue);}}}})
</script>

效果图如下:

在这里插入图片描述

1.2 vm.$watch动态监视

不仅可以给属性(即data中定义的)添加监视,也可以给计算属性添加监视。

下面例子,我们通过vm.$watch 方式,来动态给计算属性info添加监视:

<div id="root"><h2>今天我们去吃{{info}}</h2><button @click="change">切换</button>
</div>
<script>const vm = new Vue({el:'#root',data:{isHuoguo:true},computed:{info() {return this.isHuoguo?'火锅':'南京大排档';}},methods: {change() {this.isHuoguo = !this.isHuoguo;}},watch: {isHuoguo:{// immediate:true,//默认为false,初始化时,让handler调用一下。handler(newValue, oldValue) {console.log("isHuoguo属性被修改了,newValue:"+newValue+",oldValue:"+oldValue);}}}})// 监视计算属性vm.$watch('info',{// immediate:true,//默认为false,初始化时,让handler调用一下。handler(newValue, oldValue) {console.log("info计算属性被修改了,newValue:"+newValue+",oldValue:"+oldValue);}})</script>

在这里插入图片描述

1.3 深度监视(deep watch)

深度监视(deep watch):

  1. Vue中的watch默认不监测对象内部值的改变(只监测一层结构)
  2. 配置deep:true可以监测对象内部值的改变(可以监测多层结构),Vue默认不开启deep,是为了提供效率。
  3. Vue自身可以监测对象内部值的改变,但是Vue提供的watch默认不可以。
  4. 使用watch时,要根据数据的具体结构,决定是否采用深度监视。

使用方式:

  • 监视多级结构中某个属性的变化,例如下面例子中numbers.a
  • 监视多级结构中所有属性的变化,numbers:{deep:true,handler(){}}
<div id="root"><h3>今天我们去吃{{info}}</h3><button @click="change">切换</button><hr><h3>a的值是{{numbers.a}}</h3><button @click="numbers.a++">点击a++</button><hr><h3>b的值是{{numbers.b}}</h3><button @click="numbers.b++">点击b++</button>
</div>
<script>const vm = new Vue({el:'#root',data:{isHuoguo:true,numbers:{a:1,b:1}},computed:{info() {return this.isHuoguo?'火锅':'南京大排档';}},methods: {change() {this.isHuoguo = !this.isHuoguo;}},watch: {isHuoguo:{handler(newValue, oldValue) {console.log("isHuoguo属性被修改了,newValue:"+newValue+",oldValue:"+oldValue);}},// 监视多级结构中某个属性的变化"numbers.a": {handler() {console.log("a被改变了!");}},// 监视多级结构中所有属性的变化numbers:{deep:true,handler() {console.log("numbers改变了!");}}}})</script>

1.4 简写形式

当所配置的监视,只需要handler,不需要其他配置的时候,才可以使用简写形式,使用函数来代替。

两类简写形式:

  • watch配置里的简写
  • 动态添加监视的简写
<div id="root"><h3>今天我们去吃{{info}}</h3><button @click="change">切换</button>
</div>
<script>const vm = new Vue({el:'#root',data:{isHuoguo:true},computed:{info() {return this.isHuoguo?'火锅':'南京大排档';}},methods: {change() {this.isHuoguo = !this.isHuoguo;}},watch: {/* isHuoguo:{deep:true,immediate:true,handler(newValue, oldValue) {console.log("isHuoguo属性被修改了,newValue:"+newValue+",oldValue:"+oldValue);}}, */// 简写形式isHuoguo(newValue, oldValue) {console.log("isHuoguo属性被修改了,newValue:"+newValue+",oldValue:"+oldValue);}}})// 动态添加监视的简写vm.$watch('isHuoguo',function(newValue, oldValue){console.log("isHuoguo属性被修改了,newValue:"+newValue+",oldValue:"+oldValue);})</script>

二、computed和watch的对比

计算属性(computed)和监视属性(watch)之间的区别:

  1. computed能完成的功能,watch都可以完成
  2. watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。

两个重要的原则
3. 被Vue所管理的函数,最好写成普通函数,这样this的指向才是vm组件实例对象
4. 所有不被Vue管理的函数(定时器的回调函数(setTimeout)、ajax的回调函数、Promise的回调函数等),最好写成箭头函数,这样this的指向才是 vm组件实例对象

2.1 使用watch实现setTimeout操作

下面代码,使用了watch实现setTimeout操作,有一点需要注意的是,setTimeout所指定的回调函数要使用箭头函数(因为箭头函数本身没有this),否则this指向window了,而不再是vm实例。

<div id="root"><div class="row">姓:<input type="text" v-model="firstName"></div><div class="row">名:<input type="text" v-model="lastName"></div><div class="row">全名:<span>{{fullName}}</span></div>
</div><script>const vm = new Vue({el:'#root',data() {return {firstName: '小',lastName: '三',fullName:'小-三'};},methods:{},watch:{firstName(val) {setTimeout(() => {  //这里不能写成普通函数,否则this指向window了console.log(this);  //vm实例对象this.fullName = val + "-" + this.lastName;}, 1000);},lastName(val){this.fullName = this.firstName + "-" + val;}}});
</script>

2.2 用computed无法实现setTimeout

computed计算属性,无法实现setTimeout想要的功能,如下错误代码所示:

<div id="root"><div class="row">姓:<input type="text" v-model="firstName"></div><div class="row">名:<input type="text" v-model="lastName"></div><div class="row">全名:<span>{{fullName}}</span></div></div><script>const vm = new Vue({el:'#root',// 对于Vue来说,data中配置的就是属性。// 计算属性:用现有的属性去加工、计算生成一个全新的属性。和属性分开放data:{firstName: '小',lastName: '三'},computed:{fullName() {console.log('get被调用了!');// console.log(this);setTimeout(() => {return this.firstName+'-'+this.lastName}, 1000);}}});
</script>

三、其他注意事项

3.1 vue devtools的bug

当页面上没有用到某个计算属性时,vue devtools调试工具会出现一个bug:不会显示数据的变化了。例如下面代码

<div id="root"><h2>今天我们去吃米饭</h2><button @click="change">切换</button>
</div>
<script>const vm = new Vue({el:'#root',data:{isHuoguo:true},computed:{info() {return this.isHuoguo?'火锅':'南京大排档';}},methods: {change() {this.isHuoguo = !this.isHuoguo;}},})
</script>

点击切换按钮,工具中显示的datacomputed 不发生变化,其实数据已经发生了改变。可以通过控制台中输入vm.info来查看。如下图所示:

在这里插入图片描述
在这里插入图片描述

3.2 @xxx=yyy格式

这里的yyy不是事件名称,而是一些简单的语句。例如:@click="isHuoguo = !isHuoguo;count++;"

下面的案例中,两个按钮均可实现功能。不过需要注意的是,执行语句比较复杂的时候不建议直接写在yyy中。

<div id="root"><h2>今天我们去吃{{info}}--切换次数{{count}}</h2><button @click="change">切换</button><button @click="isHuoguo = !isHuoguo;count++">切换2</button>
</div>
<script>const vm = new Vue({el:'#root',data:{isHuoguo:true,count:0,},computed:{info() {return this.isHuoguo?'火锅':'南京大排档';}},methods: {change() {this.count++;this.isHuoguo = !this.isHuoguo;}},})
</script>

3.3 将window传入data中

window传入data中,实现alert弹框。如下代码所示:

<div id="root"><h2>今天我们去吃{{info}}--切换次数{{count}}</h2><button @click="change">切换</button><button @click="isHuoguo = !isHuoguo;count++">切换2</button><button @click="window.alert(1)">弹出alert</button>
</div>
<script>const vm = new Vue({el:'#root',data:{isHuoguo:true,count:0,window      //相当于window:window},computed:{info() {return this.isHuoguo?'火锅':'南京大排档';}},methods: {change() {this.count++;this.isHuoguo = !this.isHuoguo;}},})
</script>

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

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

相关文章

机器人开发--富锐雷达介绍

机器人开发--富锐雷达介绍 1 介绍参考 1 介绍 山东富锐光学科技有限公司是一家专注智能感知领域的激光雷达公司&#xff0c;致力于激光雷达前沿技术的开发和应用。 公司已累计完成数亿元融资&#xff0c;依托潍坊光电产业发展基础&#xff0c;自建生产线&#xff0c;达到年产…

LNMP安装

目录 1、LNMP简述&#xff1a; 1.1、概述 1.2、LNMP是一个缩写词&#xff0c;及每个字母的含义 1.3、编译安装与yum安装差异 1.4、编译安装的优点 2、通过LNMP创建论坛 2.1、 安装nginx服务 2.1.1、关闭防火墙 2.1.2、创建运行用户 2.1.3、 编译安装 2.1.4、 优化路…

Portraiture 4.0.3 for windows/Mac简体中文版(ps人像磨皮滤镜插件)

Imagenomic Portraiture系列插件作为PS磨皮美白必备插件&#xff0c;可以说是最强&#xff0c;今天它更新到了4.0.3版本。但是全网都没有汉化包&#xff0c;经过几个日夜汉化&#xff0c;终于汉化完成可能是全网首个Portraiture 4的汉化包&#xff0c;请大家体验&#xff0c;有…

展示Streamlit文本魔力(六):从头顶到脚尖

文章目录 1 前言✨2 st.markdown - 引入丰富的Markdown文本3 st.title - 引入引人注目的大标题4 st.header - 引入简洁的小标题5 st.subheader - 添加次级标题6 st.caption - 添加解释性文字7 st.code - 显示代码块8 st.text - 显示文本9 st.latex - 显示LaTeX公式10 st.divide…

【JAVA】 javaSE中的数组|数组的概念使用

数组的概念 什么是Java中的数组 数组&#xff1a;可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。在java中&#xff0c;包含6个整形类型元素的数组&#xff0c;可以看做是酒店中连续的6个房间. 1. 数组中存放的元素其类型相同 2. 数组的空间是连在一起的 3…

2023年第四届“华数杯”数学建模思路 - 案例:粒子群算法

# 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是粒子群算法&#xff1f; 粒子群算法&#xff08;Particle Swarm Optimization,PSO&#xff09;是一种模仿鸟群、鱼群觅食行为发展起来的一种进化算…

Maven-搭建私有仓库

使用NEXUS REPOSITORY MANAGER 3在Windows上搭建私有仓库。 NEXUS REPOSITORY MANAGER 3 是一个仓库管理系统。 下载NEXUS3 官网上是无法下载的,所以网上搜nexus-3.18.1-01-win64就能搜到,下载即可。 安装NEXUS3 下载nexus-3.18.0-01-win64.zip至相应目录下(路径不要有中文)。 …

【零基础学Rust | 基础系列 | 函数,语句和表达式】函数的定义,使用和特性

文章标题 简介一&#xff0c;函数1&#xff0c;函数的定义2&#xff0c;函数的调用3&#xff0c;函数的参数4&#xff0c;函数的返回值 二&#xff0c;语句和表达式1&#xff0c;语句2&#xff0c;表达式 总结&#xff1a; 简介 在Rust编程中&#xff0c;函数&#xff0c;语句…

c++--二叉树应用

1.根据二叉树创建字符串 力扣 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对 "()" 表示&#xff0c;转化后需要省略所有不影响字符…

vscode中无法使用git解决方案

1 首先查看git安装目录 where git 2 找到bash.exe 的路径 比如&#xff1a;C:/Users/Wangzd/AppData/Local/Programs/Git/bin/bash 3 找到vscode的配置项setting.json 4 添加 "terminal.integrated.shell.windowns": "C:/Users/Wangzd/AppData/Local/Pr…

vue2-vue中mixin到底是什么?

1、mixin是什么&#xff1f; Mixin是面向对象程序设计语言中的类&#xff0c;提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类。 Mixin类通常作为功能模块使用&#xff0c;在需要该功能时“混入”&#xff0c;有利于代码的复用又避免了多继承的复杂。 1.1 vue中…

stl_list类(使用+实现)(C++)

list 一、list-简单介绍二、list的常用接口1.常见构造2.iterator的使用3.Capacity和Element access4.Modifiers5.list的迭代器失效 三、list实现四、vector 和 list 对比五、迭代器1.迭代器的实现2.迭代器的分类&#xff08;按照功能分类&#xff09;3.反向迭代器(1)、包装逻辑…

wpf画刷学习1

在这2篇博文有提到wpf画刷&#xff0c; https://blog.csdn.net/bcbobo21cn/article/details/109699703 https://blog.csdn.net/bcbobo21cn/article/details/107133703 下面单独学习一下画刷&#xff1b; wpf有五种画刷&#xff0c;也可以自定义画刷&#xff0c;画刷的基类都…

Maven分模块-继承-聚合-私服的高级用法

Maven分模块-继承-聚合-私服的高级用法 JavaWeb知识&#xff0c;介绍Maven的高级用法&#xff01;&#xff01;&#xff01; 文章目录 Maven分模块-继承-聚合-私服的高级用法1. 分模块设计与开发1.1 介绍1.2 实践1.2.1 分析1.2.2 实现 1.3 总结 2. 继承与聚合2.1 继承2.1.1 继承…

无人机巢的作用及应用领域解析

无人机巢作为无人机领域的创新设备&#xff0c;不仅可以实现无人机的自主充电和电池交换&#xff0c;还为无人机提供安全便捷的存放空间。为了帮助大家更好地了解无人机巢&#xff0c;本文将着重解析无人机巢的作用和应用领域。 一、无人机巢的作用 无人机巢作为无人机技术的重…

【chrome扩展开发】vue-i18n使用问题及解决方案

记录chrome扩展开发时调用vue-i18n的一些问题和解决方法 环境 vue: ^3.3.4vue-i18n: ^9.2.2vite: ^4.4.8 错误1 Uncaught (in promise) EvalError: Refused to evaluate a string as JavaScript because unsafe-eval is not an allowed source of script in the following Con…

Spring Bean的生命周期

文章目录 Spring Bean的生命周期加载Bean对象创建Bean对象构造对象填充属性初始化实例注册销毁 销毁 Spring Bean的生命周期 Spring Bean的生命周期就是指Bean对象从创建到销毁的过程&#xff0c;大体可以分为&#xff1a;实例化、属性赋值、初始化、使用、销毁。 加载Bean对象…

Modelsim打开后报unable to checkout a viewer license

找到Modelsim安装包中的MentorKG.exe文件和patch64_dll.bat文件&#xff0c;将这两个文件拷贝到Modelsim安装目录中的win64文件夹&#xff1a; 在win64文件夹中找到mgls64.dll&#xff0c;将它拷贝粘贴一份后修改名字为mgls.dll&#xff1a; 双击win64文件夹中的patch64_dll.ba…

【C++】数据结构与算法:常用排序算法

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍常用排序算法。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&#x1…

Red Hat 安装MySQL 8.0与 Navicat

目录 Red Hat 安装 MySQL 8.0 1、更新软件包列表 2、安装MySQL服务器和客户端 3、启动MySQL服务 4、确保MySQL服务器正在运行 5、root 用户的密码 6、登录MySQL&#xff0c;输入mysql密码 7、MySQL默认位置 Red Hat 安装 Navicat 1、下载 Navicat 2、执行命令 Red H…