**
watch
**
watch是什么?
侦听器,vue通过watch来提供更通用的方法来响应数据变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
示例:
<div id="app">
千米:
<input type="text" v-model="kilometers" />
米:
<input type="text" v-model="meters"/>
</div>
<p id="info"></p>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
kilometers:0,
meters:0
},
watch:{
kilometers:function(val){
this.kilometers=val;
this.meters=this.kilometers*1000;
},
meters:function(val){
this.kilometers=val/1000;
this.meters=val;
}
}
});
vm.$watch('kilometers',function(newValue,oldValue){
document.getElementById('info').innerHTML='修改前值为:'+oldValue+'修改后值为:'+newValue;
})
</script>
使用场景:
当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。例如ajax请求,复杂的业务逻辑处理等。
deep属性
当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。
当监测为对象的时候(非数组情况),deep = true 可以监测对象中属性的变化,并且(监测为对象的时候,newVal == oldVal)。
不使用 deep 时,当我们改变 obj.b的值时,watch不能监听到数据变化,默认情况下,handler 只监听属性引用的变化,也就是只监听了一层,但改对象内部的属性是监听不到的。
data: {
obj: {
b: 'pp'
}
},
watch: {
obj: {
handler () {
console.log('obj.b changed')
},
deep: true
}
}
但是使用 deep 会进行属性层层遍历,性能开销比较大,只要修改 obj 中任意属性值,都会触发 handler。如何优化?在字符串中,直接写 obj 深入属性,vue 会层层解析,找到 b,并进行监听。
watch: {
'obj.b': {
handler () {
console.log('obj.b changed')
},
}
}
注意:
(1)在watch中不要使用箭头函数,即不应该使用箭头函数来定义 watcher 函数 , 因为箭头函数中的this是指向当前作用域。
(2)开启深度侦听后,触发一次,两个数据一致,这是vue做了处理
=>复杂数据类型的侦听需要开启深度侦听才可以检测到内部数据的改变,但开启深度侦听后,2个参数值是相同的,都是为数据的内存地址,精确到对象的属性名进行深度侦听可以解决此问题。
=>如果修改复杂类型内部的数据也会触发,触发的频率就回比较高,因为复杂类型数据可能多个地方使用,如果都会触发侦听器,则会一直执行,因此vue做了这个优化,不发生触发,如果非要侦听,可以使用深度侦听。
immediate属性
immediate:true代表如果在 wacth 里声明了之后,就会立即先去执行里面的handler方法,如果为 false,不会在绑定的时候就执行。
比如当父组件向子组件动态传值时,子组件props首次获取到父组件传来的默认值时,也需要执行函数,此时就需要将immediate设为true。