在 Vue.js 中,$watch 是一个实例方法,用于监视 Vue 实例中数据的变化。它的返回值是一个取消监听的函数,直接调用该函数会停止触发回调。一旦取消监听,该数据的变化将不再触发 watch 的监听。$watch 接受三个参数:
- 第一个参数:要监视的属性或表达式
- 第二个参数:回调函数,当指定的属性发生变化时,回调函数将被调用
- 第三个参数:配置参数,immediate 与 deep
- 若需要第一次运行就执行回调,可设置
{ immediate: true } - 若需要深度监听对象的变化,可设置
{ deep: true }
- 若需要第一次运行就执行回调,可设置
1# 监听基本类型:boolean、number、string
监听 boolean、number和string 类型的属性时,只需直接传入相应的变量名即可。若需要在初始化时立即执行监听,可设置 { immediate: true } 选项。
var vm = new Vue({
data: {
isActivated: false, // boolean 类型
count: 0, // Number 类型
message: 'Hello, Vue!', // string 类型
name: 'lee', // string 类型
},
created: function() {
// 监听 isActivated 属性的变化
this.$watch('isActivated', function(newVal, oldVal) {
console.log('isActivated 发生变化:', oldVal, ' => ', newVal);
});
// 监听 count 属性的变化
this.$watch('count', function(newVal, oldVal) {
console.log('count 发生变化:', oldVal, ' => ', newVal);
});
// 监听 message 属性的变化
this.$watch('message', function(newVal, oldVal) {
console.log('message 发生变化:', oldVal, ' => ', newVal);
});
// 监听 name 属性的变化,如果需要第一次就执行监听,可设置:{immediate: true}
this.$watch('name', function(newVal, oldVal) {
console.log('name 发生变化:', oldVal, ' => ', newVal);
}, { immediate: true });
},
methods: {
update: function() {
// 更新 Boolean 类型数据
this.isActivated = !this.isActivated;
// 更新 Number 类型数据
this.count++;
// 更新 String 类型数据
this.message = 'Hello, World!';
this.name = 'leaf';
}
}
});
// 调用 update 方法更新数据
vm.update();
2# 监听对象:Object
监听对象类型的属性时,可通过设置 { deep: true } 监听对象所有属性的变化,也可通过直接传入对象属性路径(如 obj.xx )监听对象单个属性的变化。前者实现深度监测对象内部值的变化,包括嵌套对象的属性变化,后者则只监听特定属性的变化,不进行深度监测。
// 创建一个 Vue 实例
var vm = new Vue({
data: {
user: {
name: 'lee',
age: 23
},
point: {
x: 0,
y: 0
}
},
created: function() {
// 监听 point 对象
this.$watch('point', function(newVal, oldVal) {
console.log('point 对象变化:', oldVal, ' => ', newVal);
});
// 监听 user 对象的 name 属性
this.$watch('user.name', function(newVal, oldVal) {
console.log('姓名变化:', oldVal, ' => ', newVal);
});
// 监听 user 对象的 age 属性
this.$watch('user.age', function(newVal, oldVal) {
console.log('年龄变化:', oldVal, ' => ', newVal);
});
},
methods: {
update: function() {
// 更新 user 对象的属性值
this.user.name = 'leaf';
this.user.age = 24;
// 更新 point 对象的属性值
this.point.x = 1;
this.point.y = 1;
}
}
});
// 调用 update 方法更新数据
vm.update();
3# 监听数组:Array
监听一维或多维数组的属性时,无需深度监听,因为 Vue.js 默认可以捕捉数组的变化。但是,如果需要监测数组对象中的对象属性变化,就需要使用 { deep: true } 深度监听。这样可以确保无论对象属性变化发生在多少层内,都能被正确监测到。
// 创建一个 Vue 实例
new Vue({
data: {
// 包含一维数组
flatArray: [1, 2, 3],
// 包含二维数组
nestedArray: [[1, 2], [3, 4]],
// 包含对象的一维数组
objectArray: [
{ name: 'Item 1', value: 10 },
{ name: 'Item 2', value: 20 }
]
},
created() {
// 监听一维数组 flatArray 的变化
this.$watch('flatArray', (newVal, oldVal) => {
console.log('一维数组发生变化', newVal, oldVal);
}, { deep: true });
// 监听二维数组 nestedArray 的变化
this.$watch('nestedArray', (newVal, oldVal) => {
console.log('二维数组发生变化', newVal, oldVal);
}, { deep: true });
// 监听包含对象的一维数组 objectArray 的变化
this.$watch('objectArray', (newVal, oldVal) => {
console.log('包含对象的一维数组发生变化', newVal, oldVal);
}, { deep: true });
},
methods: {
update() {
// 更新一维数组
this.flatArray.push(4);
// 更新二维数组
this.nestedArray[0].push(5);
// 更新包含对象的一维数组
this.objectArray[0].value = 15;
}
}
});
// 调用 update 方法更新数据
vm.update();
注意:
$watch监视数组的不足之处在于,它只能捕捉到数组本身的变化,例如数组长度的变化、元素的添加或删除,而无法深度监测数组内部元素的变化,特别是对数组中对象属性的修改,即如果对数组中的对象进行修改、添加或删除操作,$watch是无法触发回调函数的;此外,对于大型数组或深度嵌套的数组,由于每次数组发生变化时,都会触发回调函数,使用$watch监视器可能会影响应用程序的响应性能。因此建议使用$set方法或侦听器来处理数组变化。