vue项目使用watch监听器监听数据变化

1.概述

在开发项目中,有些场景是当用户点击某个按钮后改变某个属性的值,这个值改变时需要触发事件做一些事情。属性值什么时候改变是没法提前判断的,因此需要有个监听的角色,当监听到值改变后触发事件。

2.watch基本使用方法

watch的基本使用方法就可以满足大部分的监听场景,下面使用具体的例子介绍watch如何使用。
watch基础用法就是当值第一次绑定的时候,不会执行监听函数,只有当值发生改变时才会执行。如果我们需要在最初绑定值的时侯,也执行监听函数,则看后面高级用法。

2.1.把属性当做方法监听

下面监听name属性值的碧昂华,在watch中把它当做一个方法,监听该属性的值。

<template>
	<el-card class="box-card"><el-input v-model="name" style="width: 30%;"></el-input></el-card>
</template>
 
<script>
export default {
	data() {
		return {
			name: '123'
		};
	},
	watch: {
		name(newVal, oldVal) {
			console.log('newVal', newVal);// 1234
			console.log('oldVal', oldVal);// 123
		}
	}
};
</script>
 
<style></style>

2.2.把属性当做对象监听

把要监听的name值看作对象,利用hanler方法来进行监听。

<template>
	<el-card class="box-card"><el-input v-model="name" style="width: 30%;"></el-input></el-card>
</template>
 
<script>
export default {
	data() {
		return {
			name: '123'
		};
	},
	watch: {
		name:{
			handler(newVal,oldVal){
				console.log('newVal',newVal); // 1234
				console.log('oldVal',oldVal); // 123
			}
		}
	}
};
</script>
 
<style></style>

3.watch高级用法

3.1.设置是否监听属性初始值

当父组件向子组件动态传值时,子组件props首次获取到父组件传来的默认值时,也需要执行函数,此时就需要将immediate属性设置为true,结合handler方法使用。

  • 当设置immediate属性为true时,无论值是否发生改变,时刻都会监听。
  • 当设置immediate属性为false时,常规用法,只有值发生改变才会监听。
<template>
	<el-card class="box-card"><el-input v-model="name" style="width: 30%;"></el-input></el-card>
</template>
 
<script>
export default {
	data() {
		return {
			name: '123'
		};
	},
	watch: {
		name: {
			handler(newVal, oldVal) {
				console.log('newVal', newVal);
				console.log('oldVal', oldVal);
			},
			immediate: true
		}
	}
};
</script>
 
<style></style>

3.2.监听对象内部属性值

前面我们监听的都是一个属性,如果被监听的不是一个属性而是一个对象,那么上面的方式是监听不到对象里面属性值的变化,需要用deep深度监听。

例如下面监听的form是一个对象,里面name是一个属性。普通的方式是监听不到form里面name的变化,使用deep后才可监听到。

<template>
	<el-card class="box-card"><el-input v-model="form.name" style="width: 30%;"></el-input></el-card>
</template>
 
<script>
export default {
	data() {
		return {
			form: {
				name: '123'
			}
		};
	},
	watch: {
		form: {
			handler(newVal, oldVal) {
				console.log('newVal', newVal);
				console.log('oldVal', oldVal);
			},
			// 深度监听,form对象内部name属性变化
			deep: true
		}
	}
};
</script>
 
<style></style>

3.3.监听对象中具体的属性

当我们监听对象时使用上面的deep深度监听是可以监听到对象中所有属性值变化,如果我们非常明确只需要监听对象中具体的属性,指定监听的属性后不用deep深度也可以监听到。

<template>
	<el-card class="box-card"><el-input v-model="form.name" style="width: 30%;"></el-input></el-card>
</template>
 
<script>
export default {
	data() {
		return {
			form: {
				name: '123'
			}
		};
	},
	watch: {
		// 指定监听对象中具体的属性
		'form.name': {
			handler(newVal, oldVal) {
				console.log('newVal', newVal);
				console.log('oldVal', oldVal);
			}
		}
	}
};
</script>
 
<style></style>

3.4.多层级嵌套用深度监听

如果监听的对象是一个多层级结构,那么使用深度监听可以监听到每一层的数据。
例如下面监听arr1 和 arr2 两个数组里面包含了嵌套层级的对象,使用深度监听。

<template>
	<el-card class="box-card"><el-input v-model="name" @input="inputFn" style="width: 30%;"></el-input></el-card>
</template>
 
<script>
export default {
	data() {
		return {
			name: '123',
			arr1: [
				{
					id: 1,
					sex: 11
				}
			],
			//监听多层嵌套对象
			arr2: [
				{
					id: 2,
					sex: 22,
					list: [
						{
							id: 3,
							sex: 33
						}
					]
				}
			]
		};
	},
	watch: {
		arr1: {
			handler(newVal, oldVal) {
				console.log('newVal1', newVal);
				console.log('oldVal1', oldVal);
			},
			deep: true
		},
		arr2: {
			handler(newVal, oldVal) {
				console.log('newVal2', newVal);
				console.log('oldVal2', oldVal);
			},
			deep: true
		}
	},
	methods: {
		inputFn(e) {
			this.arr1[0].sex = e;
			this.arr2[0].list[0].sex = e;
		}
	}
};
</script>
 
<style></style>