# 侦听器 watch

# 介绍

侦听器 watch 可以用来监听一个数据的变化。watchcomputedmethods 一样,都是一个对象。所以,他们都使用:{}的方式,并且处于同一级别。


data () {
    return {
        count: 0
    }
}

watch: {

},
computed: {

},
methods: {

}

# watch

我们知道,computed 里面添加的是一个新值,并且可以在任何地方使用。而 watch 里面添加的是一个已经存在的表达式(变量)。watch 的使用方式分为好几种,下面我们来具体说明一下:

  • 普通方式
computed: {
  count: (newValue, oldValue) {
      console.log('newValue', newValue)
      console.log('oldValue', oldValue)
  }
}

此时我们就已经设置好了对变量count进行了监听。如果count的值改变,那么会打印出对应的值。其中,newValue代表新值,oldValue代表旧值(newValue 和 oldValue 的名字可以随意更改,只代表第一个参数和第二个参数而已)。

比如说,count初始化为 0, 那么我们把count = 1。此时,newValue为 1,oldValue为 0。

  • 使用方法
methods: {
    countHandler: function(newValue, oldValue) {
      console.log('newValue', newValue)
      console.log('oldValue', oldValue)
    }
}

computed: {
    count: 'countHandler'
}

这种方式和上面是同样的效果。

  • 使用handler(deep)
computed:{
    count: {
        handler: (newValue, oldValue) {
            ...
        },
        deep: true
    }
}

注意这里有一个depp选项,官网中的解释如下:

该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深

正常来说,我们使用 watch 监听的是单个值,watch 能够正常使用。而如果是一个对象的话,那么 watch 只会监听到内存地址的改变,而监听不到对象里面值的改变。

假如有如下代码:


data () {
    return {
        obj: {
            name: 'tim'
        }
    }
}

watch: {
    obj: function(newVal, oldVal) {
        console.log('newVal', newVal)
        console.log('oldVal', oldVal)
    }
}

我们设置了对 obj 对象的监听,当我们改变 obj 时:

this.obj = {
  name: 'sam'
}

如上图所示,我们能够看到,控制台打印出了对应的信息,说明我们能够监听到。但是我们改变obj里面的值呢?我们把代码做一下改变:

this.obj.name = 'sam'

现在我们再看一下控制台,发现没有任何打印信息出现,说明我们没有监听到name属性。实际上,我们对obj设置了watch,只是监听了它的内存地址,如果obj的内存地址改变了,watch才会响应。 (有关内存地址,可以网上找一下const声明对象的原理)

那么我们想要监听到obj里面的属性,或者说监听name属性,我们有两种方法:

  1. 其一是,如上面所示,我们可以给watchobj里面添加deep: true这一条属性,代表我们进行深度监听。但是obj里面的任何值改变,该函数都会执行。

加上了deep: true属性后,发现控制台打印出了对应的newValoldVal了。

  1. 其二是,对name属性进行单独的监听,可以进行如下设置:
computed: {
    'obj.name': function(newVal, oldVal) {
        // ...
    }
}

这样,只要obj.name的值改变,才会执行对应的函数!

  • 使用方法(immediate)
computed: {
    count: {
      handler: function(newVal, oldVal) {},
      immediate: true
    },
}

可以看到,我们又换了一个属性immediate,什么意思呢?来自官网的解释如下:

该回调将会在侦听开始之后被立即调用

这里比较好理解,意思就是,设置监听后,会立马调用监听的函数。正常来说,最开始的几种方法在页面加载完毕后,都不会打印newVal。而设置了immediate属性后,页面加载完毕控制台就会打印出newVal

还有其他方法请查看官方文档

以上说了一大堆方法可能大家有点蒙,别着急,目前我日常使用过程中,比较常用的就是:


computed: {
    count(newVal, oldVal) {
        // ...
    }
    // 或者
    'obj.name'(newVal, oldVal){
        // ...
    }
}

侦听器固然好用,但是也会造成滥用,那么官方文档里面有对应的例子,这里就不在细说了。

上次更新: 2/3/2020, 9:47:35 PM