在Vue中经常使用watch来检测数据的变化,以及做出相应的反馈
- 变量的监听
watch最简单的最基础的监听方式
<input type="text" v-model="name">{{watchName}}</input>
export default {
name: 'Hello',
data() {
return {
name: '',
watchName: ''
}
},
watch: {
name(val) {
this.watchName = val;
}
}
}
也可以写一个监听处理函数
// 在method中写
nameChange () {
this.watchName = this.name;
}
- 对象监听
<input type="text" v-model="formItem.name">{{watchObjName}}</input>
'formItem.name' (val) {
this.watchObjName = val;
}
借助computed计算属性来完成监听:
watch: {
name: 'nameChange',
newName (val) {
this.watchObjName = val;
}
},
computed: {
newName () {
return this.formItem.name;
}
}
immediate和handler
上面watch的使用方法:当第一次绑定的时候是不会执行监听函数的,只有值发生改变才会执行
若需要在值最初绑定的时候也执行函数,就需要用到 immediate属性:比如父给子传值时,子组件props首次获取到父组件传来的默认值时,就需要将immediate设为true
// 监听数据后面写成对象形式,包含handle方法和immediate方法
// 之前写得函数其实就是在写这个handle方法
watch: {
name: {
handler (val) {
this.watchName = val;
},
immediate: true
}
}
immediate表示在watch中首次绑定的时候,是否执行handler,看immediate的值为true,则表示在watch中声明时,就立即执行handler方法;值为false,则跟一般使用watch一样,只在数据发生变化时执行handler。
deep深度监听
当需要监听复杂的数据类型(对象)的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能监听到变化,此时就需要使用deep属性:
// 两种写法,看情况择其一
// 监听对象所有属性
watch: {
person: {
handler (val) {
console.log('深度监听', val);
}
deep: true,
// 当然也可以加上handler
handler: true
}
}
// 只监听对象的一个属性
watch: {
'watchObj.name': {
handler(newName, oldName) {
console.log('深度监听', name);
},
deep: true,
immdiate: true
}
}
一般深度监听结果是这样的:
{__obj__: Observer};
设置deep属性后,给watchObj的所有属性都加上这个监听器,不管这个对象属性有多少,每个属性值变化都会执行handler;
如果只需要监听对象的一个属性的值,则可以使用字符串的形式监听对象属性,也就是对象监听
数组(一维、多维)的变化不需要通过深度监听;对象数组中对象的属性变化则需要deep深度监听
使用时注意:
- 在watch中不要使用箭头函数,即不应该使用箭头函数来定义watcher函数,其中原因便是this指向问题。
- 开启深度监听后,触发一次,两处的数据一致,这是Vue做了数据处理。