记录我的Vue.js从会用到精通之路 6

198 阅读2分钟

侦听器 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有更适合使用它的地方!