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>
相关推荐
Hello-Mr.Wang16 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘43 分钟前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
编程零零七4 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
(⊙o⊙)~哦6 小时前
JavaScript substring() 方法
前端
无心使然云中漫步6 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者7 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_7 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
麒麟而非淇淋8 小时前
AJAX 入门 day1
前端·javascript·ajax
2401_858120538 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab
阿树梢8 小时前
【Vue】VueRouter路由
前端·javascript·vue.js