在Vue.js框架中,watch
是一个非常强大的特性,它用于监听数据变化并在数据变化时执行特定的操作。watch
主要用于处理更复杂的逻辑,当简单的计算属性无法满足需求时,或者需要在数据变化时执行异步操作、执行开销较大的计算,或者执行一些副作用时,watch
就显得尤为重要。
举个栗子
监听单个属性
当message
属性的值发生变化时,关联的函数才会被调用
<template>
<div id="app">
<div>
<p>message:{{message}}</p>
<!-- 在这对message进行修改时触发watch -->
<p>message:<input type="text" v-model="message"/></p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello Vue!'
};
},
watch: {
message(newValue,oldValue){
//newValue更新的值,oldValue原来的值
console.log(newValue,oldValue);
}
}
};
</script>
使用对象形式定义
watch: {
message: {
handler(newVal, oldVal) {
console.log(`message changed from "${oldVal}" to "${newVal}"`);
},
// 是否在初始绑定时立即调用一次handler函数
immediate: true,
// 是否深度监听对象内部的属性变化
deep: true
}
}
handler
: 必需,监听器的处理函数,当被监听的数据变化时调用。immediate
: 可选,默认为false
。如果设置为true
,则在watcher
被初始化时立即调用一次handler
函数。deep
: 可选,默认为false
。如果被监听的数据是对象,设置为true
后可以进行深度监听,即对象内部属性的变化也会被监听到。(此时会给对象的所有属性都加上这个监听器,当对象属性较多时,每个属性值的变化都会执行handler。)- 如果只想对对象的某个属性值进行监听,也可以使用字符串的形式监听对象属性:
-
watch:{ 'person.age':{ handler(newValue,oldValue){ //... }, deep:true, immediate:true } }
注意事项
- 不要在
watch
的处理函数中修改正在监听的属性,这可能导致无限循环调用。 - 避免使用箭头函数定义
handler
,因为箭头函数没有自己的this
,这会导致this
指向问题。 - 性能考虑:深度监听 (
deep: true
) 会带来性能开销,特别是当监听大型对象或数组时,应谨慎使用。 - 与
computed
的区别:computed
适合计算衍生状态,且计算结果会被缓存;watch
则用于执行副作用或处理复杂逻辑。
如果想在同一个函数内处理多个属性的变化,可以创建一个单独的函数来监听这些属性,并在watch
中分别为它们定义监听器。
export default {
data() {
return {
propA: '',
propB: '',
};
},
watch:{
propA:function handleChanges(newValue,oldValue){
this.commonHandler('propA',newValue,oldValue);
},
propB:function handleChanges(newValue,oldValue){
this.commonHandler('propB',newValue,oldValue);
}
},
methods:{
commonHandler(propname,newValue,oldValue){
console.log(`${propname}的值from ${oldValue} to ${newValue}`);
}
}
}