Vue学习笔记(六):监视属性

1 监视属性[¶](#1 监视属性¶)

监视属性是一种用于监视某个数据的变化,并触发相应的回调函数执行的机制。在vue内部,使用"wathch"关键字用于声明监视属性。

1.1 基本用法[¶](#1.1 基本用法¶)

(1)添加watch属性,值为一个对象。对象的属性名就是要监视的数据,属性值为回调函数,每当这个属性名对应的值发生变化,就会触发该回调函数执行

(2)回调函数有2个参数:

newVal:数据发生改变后的值

oldVal:数据发生改变前的值

例如,我们定义一个变量num,在页面中添加一个按钮,每点击一次按钮,num的值加1,另外,每次在num的值发生改变时,控制台输出提示。

复制代码
<!-- 准备好一个容器-->
    	<div id="root">
    		<h2>num的值为:{{num}}</h2>
    		<button @click="changeNum">点击num+1</button>
    	</div>
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				num: 0
    			},
    			methods: {
    				changeNum(){
    					this.num = this.num + 1
    				}
    			},
    			watch:{
    				num(newVal, oldVal){   // newVal为修改后的值, oldVal为修改前的值
    					console.log('num的值发生了变化')
    					console.log(newVal,oldVal)
    				}
    			}
    		})
    	</script>

1.2 监听对象内部属性的变化[¶](#1.2 监听对象内部属性的变化¶)

前面的例子只是监听data中的第一层数据,如果要监听多层次的数据,例如a.b.c,则属性名需要用引号包裹起来.

复制代码
<div id="root">
    		<h2>a的值为:{{num.a}}</h2>
    		<h2>num的值为:{{num}}</h2>
    		<button @click="changeA">点击a+1</button>
    		<button @click="changeNum">修改num</button>
    	</div>
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				num: {
    					a: 0,
    					b: 0
    				}
    			},
    			methods: {
    				changeA(){
    					this.num.a = this.num.a + 1
    				},
    				changeNum(){
    					this.num = {a:100, b:200}
    				}
    			},
    			watch:{
    				"num.a"(newVal, oldVal){  // 注意:此时,因为a是对象内部变量,所以a必须用"num.a"的方式用双引号包裹
    					console.log('a的值发生了变化')
    					console.log(newVal,oldVal)
    				},
    				num(newVal, oldVal){  // newVal为修改后的值, oldVal为修改前的值
    					console.log('num的值发生了变化')
    					console.log(newVal,oldVal)
    				}
    			}
    		})
    	</script>

如下图所示,第一次点击"点击a+1"按钮,a的值加了1,控制台输出了两行;第一次点击"修改num"按钮,因为a的值也同时发生改变,所以a的监视属性也触发,因为num完整修改了,所以,num的监视属性也修改了。所以会有4行输出结果在控制台。

1.3 深度监听[¶](#1.3 深度监听¶)

监视属性只能监听到当前对象值的变化,而对象内部的属性变化不会监听到,前面1.2节我们监听了num和num.a,修改了num.a并不会触发监听num的监听属性。 想要监听对象内部的属性值变化,需要进行相应的配置。

  • deep:深度监听,默认false,当对象内部深层属性变量发生修改时,是否触发

  • handler:回调函数

  • immediate: 页面初始化时是否触发回调,默认false

如下所示,我们只监听num对象,但修改num对象内部的变量a时,num的监听属性也被触发,这就是深度监听的作用:

复制代码
<div id="root">
    		<h2>a的值为:{{num.a}}</h2>
    		<button @click="changeA">点击a+1</button>
    	</div>
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				num: {
    					a: 0,
    					b: 0
    				}
    			},
    			methods: {
    				changeA(){
    					this.num.a = this.num.a + 1   // 注意:此处修改的是a的值,而不是整个num
    				}
    			},
    			watch:{

    				num: {  // 监听num对象
    					deep: true, // 深度监听
    					handler:function(newVal,oldVal){  // 监听属性的回调方法
    						console.log('num的值发生了变化')
    						console.log(this.num.a, this.num.b)
    					},
    					immediate:true  // 页面初始化时是否触发回调
    				}
    			}
    		})
    	</script>

点击一次按钮,控制台输出两次,第一次是因为imediate设置为了true,当页面初始化时,会自动出发一次num的监视属性,第一次是点击按钮触发。

1.4 监视属性的简写[¶](#1.4 监视属性的简写¶)

在1.3节说到,监视属性有三种属性,即deep、imediate、handler,当deep和imediate两个属性不需要使用(使用默认值时),可以使用简写形式,下方代码中,被注释的完整形式和简写形式作用是一样的:

复制代码
<div id="root">
    		<h2>a的值为:{{num}}</h2>
    		<button @click="changeNum">点击a+1</button>
    	</div>
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				num: 0
    			},
    			methods: {
    				changeNum(){
    					this.num = this.num + 1   // 注意:此处修改的是a的值,而不是整个num
    				}
    			},
    			watch:{
    				// 完整写法
    				// num: {  // 监听num对象
    				// 	deep: false, // 深度监听
    				// 	immediate:false,
    				// 	handler:function(newVal,oldVal){  // 监听属性的回调方法
    				// 		console.log('num的值发生了变化')
    				// 		console.log(newVal,oldVal)
    				// 	},
    					
    				// }
    				// 简写形式
    				num(newVal,oldVal){
    					console.log('num的值发生了变化')
    					console.log(newVal,oldVal)
    				}
    			}
    		})
    	</script>

1.5 创建监视属性的另一种方式[¶](#1.5 创建监视属性的另一种方式¶)

监视属性也可以在创建完vue实例之后再添加:

复制代码
<div id="root">
    		<h2>a的值为:{{num}}</h2>
    		<button @click="changeNum">点击a+1</button>
    	</div>
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				num: 0
    			},
    			methods: {
    				changeNum(){
    					this.num = this.num + 1   // 注意:此处修改的是a的值,而不是整个num
    				}
    			},
    		})

    		// 为num添加监视属性
    		vm.$watch('num',{  // 指定监视num
    		immediate:true, //初始化时让handler调用一下
    		handler(newValue,oldValue){
    			console.log('num被修改了',newValue,oldValue)
    		}
    	})
    	</script>

2 计算属性与监视属性的对比[¶](#2 计算属性与监视属性的对比¶)

  • 计算属性能完成的功能,监视属性都能完成
  • 监视属性能完成的部分功能,计算属性不一定能完成,例如涉及异步操作的功能
  • 如果两者都能完成的功能,建议使用计算属性,效率更高

如下所示,连个输入框分别双向绑定两个变量:num1和num2,在输入框下方输出两个变量的和,要求无论哪个变量发生修改,延迟3秒后,再求和并输出。因为涉及的延迟输出,计算属性就不能完成了,这时候要使用监视属性:

复制代码
<div id="root">
    		num1:<input type="text" v-model="num1"> <br/><br/>
    		num2:<input type="text" v-model="num2"> <br/><br/>
    		sum:<span>{{sum}}</span> <br/><br/>
    	</div>
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
    		const vm = new Vue({
    			el:'#root',
    			data:{
    				num1: 0,
    				num2: 0,
    				sum: 0
    			},
    			watch:{
    				num1(val){
    					setTimeout(()=>{
    						console.log(this)
    						this.sum = parseInt(this.num1) + parseInt(this.num2)
    					},3000);
    				},
    				num1(val){
    					setTimeout(()=>{
    						console.log(this)
    						this.sum = parseInt(this.num1) + parseInt(this.num2)
    					},3000);
    				},
    			}
    		})
    	</script>
相关推荐
IT_陈寒12 小时前
Python开发者必看:这5个鲜为人知的Pandas技巧让你的数据处理效率提升50%
前端·人工智能·后端
豆苗学前端12 小时前
写给女朋友的第一封信,测试方法概论
前端·后端·设计模式
半桶水专家12 小时前
Vue 3 插槽(Slot)详解
前端·javascript·vue.js
袁煦丞12 小时前
本地AI绘画神器+全局访问——Stable Diffusion WebUI 成功突破:cpolar内网穿透实验室第462个成功挑战
前端·程序员·远程工作
一枚前端小能手12 小时前
🏗️ JavaScript类深度解析 - 从构造函数到现代特性的完整指南
前端·javascript
袁煦丞12 小时前
家用NAS+云盘自由NanoPi R4S+iStoreOS:cpolar内网穿透实验室第460个成功挑战
前端·程序员·远程工作
浏览器API调用工程师_Taylor13 小时前
日报自动化实战:告别手动复制粘贴
前端·javascript·node.js
晴殇i13 小时前
JavaScript还能这样写?!ES2025新语法让代码优雅到极致
前端·javascript·程序员
浏览器API调用工程师_Taylor13 小时前
我是如何将手动的日报自动化的☺️☺️☺️
前端·javascript·爬虫
前端Hardy14 小时前
HTML&CSS&JS:抖音爆火的满屏“关心弹幕”酷炫卡片,已经帮你打包好了,快来体验吧!
前端·javascript·css