Watcher的作用
监测数据(data)或计算属性(computed property)的值,当该值发生变化时,自动执行相应代码。
下面代码(Vue 2版本)会监测当加速时,如果速度超过70,会提醒:
JavaScript
export default {
// ...
data() {
return {
speed: 0
}
},
// methods: () ,
// computed: {},
watch: {
speed(newValue, oldvalue) {
if(newValue > oldValue && newValue === 70) {
alert('You have reached the speed limit!');
}
}
}
}
Vue 3版本:
JavaScript
<template>
Speed: {{ speed }}<br/>
<button @click="speed+=10">Click me</button>
</template>
<script>
import { ref, watch } from 'vue'
export default {
name: 'Demo',
setup() {
let speed = ref(0)
watch(speed, (newValue, oldValue) => {
console.log("Speed", newValue, oldValue);
})
return {
speed
}
}
}
如果要监视多个ref定义的响应式数据:
JavsScript
watch([speed, message], (newValue, oldValue) => {
// ...
})
监视reactive所定义的数据
JavaScript
let student = reactive({
id: '9901',
name: 'Paul',
score: 90
})
watch(student, (newValue, oldValue) => {
// 注意,在当前Vue3版本中似乎无法获取oldValue
// 同时,强制开启了deep watch,也就是说这个设置项无效
})
如果只监视reactive对象的某个属性:
JavaScript
watch(()=> return student.score, (newValue, oldValue) => {
// ...
})
如果监视reactive对象的多个属性:
JavaScript
watch([()=> return student.score, ()=> return student.name], (newValue, oldValue) => {
// ...
})
如果要监视嵌套对象的某个属性,需要添加deep:true
JavaScript
let student = reactive({
id: '9901',
name: 'Paul',
score: {
math: 99,
chinese: 90,
physics; 80
}
})
watch([()=> return student.score, ()=> return student.name], (newValue, oldValue) => {
// ...
}, {deep:true})
Watcher vs Computed properties
严格讲,可以使用watcher来替代计算属性,但一般不会这么做。一般情况下,计算属性的代码更为简洁,而watcher的代码会相对复杂些。
计算属性应用场景:
- 从现有属性计算出推导属性
- 减少变量长度:有些时候,需要好几个步骤才能推导出UI想要的属性值,这时需要使用计算属性
使用Watcher的场景:
- 监测某个属性值,当达到某个阈值时触发相应操作
- 当属性值发生变化时,需要调用一个API
- 当需要根据旧值和新值进行特定处理时
Immediate Watcher
在默认情况下,页面被加载时,属性被初始化,但这个初始化操作并不会触发watcher。如果想要这样做的话,可以对watcher稍作修改(Vue 2版本):
JavaScript
watch: {
speed: {
handler(newValue, oldvalue) {
if(newValue > oldValue && newValue === 70) {
alert('You have reached the speed limit!');
}
},
immediate: true,
}
}
Vue 3版本
JavaScript
watch(speed, (newValue, oldValue) => {
console.log("Speed", newValue, oldValue);
}, {immediate: true})
以上这种方式在需要调用API时可能会经常用到。
Deep Watcher
在默认情况下,Vue不会监测对象属性值的变化。如果想要实现这样的功能,需要使用deep属性:
markup
studentInfo: {
handler(newValue) {
// making API calls
console.log(newValue.id, newValue.name);
},
deep: true
}