Watch(侦听器)
作用:监听某一个属性发生变化时候需要执行的操作。
场景:当一条数据改变,影响多条数据的时候。(计算属性:当多条数据改变影响一条数据的时候。如:购物车 商品总价格)。
示例:
1.监听属性,用属性名作为函数名,接收两个参数分别是:新值(改变后的值) 旧值(改变前的值)。
data() {
return {
count: 0,
person: {
name: '张三',
age: 18,
son: {
name: '张四',
age: 1
}
}
}
},
watch:{
count(newVal, oldVal) {
console.log(`触发watch监听-----新值是${newVal},旧值是${oldVal}`);
},
}
2.监听对象属性,对象属性名要加单引号'person.son.name',接收两个参数分别是:新值(改变后的值) 旧值(改变前的值)。
data() {
return {
count: 0,
person: {
name: '张三',
age: 18,
son: {
name: '张四',
age: 1
}
}
}
},
watch:{
'person.son.name'(newVal, oldVal) {
console.log(`触发watch监听-----新值是${newVal},旧值是${oldVal}`);
},
}
3.监听对象里面所有属性。
需要设置deep为true表示深度监听对象里面的所有属性。
immediate(立即的) watch监听数据发生改变的时候才会触发,设置此属性为true,在组件创建的时候就会触发,也就是数据初次加载就会触发。
data() {
return {
count: 0,
person: {
name: '张三',
age: 18,
son: {
name: '张四',
age: 1
}
}
}
},
watch:{
person: {
handler(newVal,oldVal){
console.log(newVal); //打印的是person对象改变后的值 此时person.son.name是王五
console.log(oldVal);
},
deep:true, //深度监听默认是false 递归监听对象里面的属性
immediate: true //在组件创建的时候立即执行
}
}
完整示例
el: '#app',
data() {
return {
count: 0,
person: {
name: '张三',
age: 18,
son: {
name: '张四',
age: 1
}
}
}
},
mounted() {
//1秒后改变son里面的name属性
setTimeout(() => {
this.person.son.name = '张五'
}, 1000);
//每隔1秒让count加一
setInterval(() => {
this.count++
}, 1000);
},
watch: {
//监听属性
count(newVal, oldVal) {
console.log(`触发watch监听-----新值是${newVal},旧值是${oldVal}`);
//触发watch监听----- 新值是1, 旧值是0
//触发watch监听----- 新值是2, 旧值是1
//触发watch监听----- 新值是3, 旧值是2
//触发watch监听----- 新值是4, 旧值是3
},
//监听对象属性
'person.son.name'(newVal, oldVal) {
console.log(`触发watch监听-----新值是${newVal},旧值是${oldVal}`);
//触发watch监听-----新值是张五,旧值是张四
},
//监听整个对象的所有属性(一般不建议使用)
person: {
handler(newVal,oldVal){
console.log(newVal); //打印的是person对象改变后的值 此时person.son.name是王五
console.log(oldVal);
},
deep:true, //深度监听默认是false 递归监听对象里面的属性
immediate: true //在组件创建的时候立即执行
}
}
})
对比Watch和Computed的使用场景
watch 用于一个数据改变影响多条数据。
computed用于多条数据影响一条数据。
计算属性(computed)是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。
这就意味着只要值还没有发生改变,多次访问计算属性会立即返回之前的计算结果,而不必再次执行计算属性。
而methods只要调用就会触发。
比如购物车计算总价格,如果使用watch则需要监听每个属性的改变,代码冗余较多。
示例
const app = new Vue({
el: '#app',
data() {
return {
applePrice: 20, //单价
appleCount: 1, //数量
bananaPrice: 30,
bananaCount: 1,
allPrice:0
}
},
mounted() {
//1秒后改变修改数量
setTimeout(() => {
this.bananaCount = 2;
this.appleCount = 3;
}, 1000);
},
computed: {
resultPrice(){
let result = this.applePrice * this.appleCount + this.bananaPrice * this.bananaCount;
return result;
}
},
watch: {
//需要对所有属性进行监听不合理。
appleCount() {
this.allPrice = this.applePrice * this.appleCount + this.bananaPrice * this.bananaCount;
},
bananaCount() {
this.allPrice = this.applePrice * this.appleCount + this.bananaPrice * this.bananaCount;
},
}
})