侦听器 watch
watch可以监听数据的变化来作出相应。
watch的写法是多种多样的
watch对象中key是监听目标,而value值由多种:
-
使用最多的:value是对应的watcher函数
watch : { targetName : function(newValue,oldValue){ // target的值一旦改变,函数执行。 // 如果target是对象,即使target上的某个属性改变,由于对象的指向 没变,所以并不会触发watcher函数。 } } -
value是方法名
watch:{ targetName : 'someMethod' } -
value是对象,使用这种方式,要掌握handler、deep、immediate三个属性。
watch:{ targetName : { handler : function(newValue,oldValue){ //... }, deep : true/false, immediate : true/fasle } }handler也就是watcher函数,这个就不必长篇大论了。
那这里的deep属性与immediate属性起什么作用呢?
我们先说immediate这个属性,默认值是false。当我们将其设置为true的时候,该回调将会在侦听开始之后被立即调用!
这是啥意思呢?
当它为false的时候,watcher函数的执行,取决于target的改变。如果它不改变,那咱的watcher函数就无法执行。但是当它为true的时候,不管三七二十一,在target成功初始化的时候,就先把watcher函数跑一遍。
const vm = new Vue({ el : '.demo', data : { name : '97T' }, watch:{ name : { handler(newVal,oldVal){ console.log('handler is runing!') }, immediate : true // 默认值为false } } })再来看deep这个属性,默认值是false。官方的解释是这样的:
该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深。
也就是说即使target的引用值没有改变,但是监听器会一层层的往下遍历,监听每一个属性,那这样性能开销就非常大了。我们可以使用字符串形式监听来优化:
const vm = new Vue({ el : '.demo', data : { obj : { name : 'dog', age : 3 } }, watch:{ 'obj.name' : function(){ console.log('obj.name is change'); // 如果obj.age发生改变,并不会触发这个watcher函数。 } } })
watch注销
说实话,这次拜读文档是我第一次听这个词,那一起来看看吧。
通常我们在开发中,会大量的使用组件,而watch往往都在组件中,它会随着组件的销毁而销毁,往往我们不需要手动销毁。
但是!如果你非要按下面这么写,咱也不能拦着你!
const app = new Vue({
//...
})
const unWatch = app.$watch('target',function(){
//...
})
那这该如何注销呢?
其实app.$watch调用后的返回值就是对应的注销方法
unWatch() //手动注销
回到我们昨天的问题:computed VS watch
个人的想法是虽然watch也可以实现computed,但是他俩各有所长,虽然computed经常使用,但是watch有更适合使用它的地方!