Bootstrap

130-Vue中的监听事件——Watch

Watch

watch的作用可以监控一个值的变换,并调用因为变化需要执行的方法。可以通过watch动态改变关联的状态。

简单点说,就是实时监听某个数据的变化。

1、普通监听

<template>
<!-- 监听属性 -->
  <div>
    <p>{{num}}</p>
    <button @click="num++">按钮</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      num:30
 
    }
  },
  watch:{
    // 第1种格式:
    // num(newVal,oldVal){
    //   // 什么时候执行, num的值发生变化的时候,就执行这里的代码
    //   console.log("num被修改了",newVal,oldVal);
    // },
    // 第2种格式:
    num:{
      handler(newVal,oldVal){
        // 什么时候执行, num的值发生变化的时候,就执行这里的代码
        console.log("num被修改了",newVal,oldVal);
      }
    }
  }
}
</script>
 
<style lang = "less" scoped>
  
</style>

2、立即监听

如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。

<template>
<!-- 立即监听 -->
  <div>
    <p>{{num}}</p>
    <button @click="num++">按钮</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      num:30
 
    }
  },
  watch:{
    num:{
      handler(newVal,oldVal){
        // 什么时候执行, num的值发生变化的时候,就执行这里的代码
        console.log("num被修改了",newVal,oldVal);
      },
      immediate:true   // 立即监听
    }
  }
}
</script>
 
<style lang = "less" scoped>
  
</style>

immediate需要搭配handler一起使用,其在最初绑定时,调用的函数也就是这个handler函数。

3、深度监听

当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。

<template>
<!-- 深度监听 -->
  <div>
    <p>{{obj.age}}</p>
    <button @click="obj.age++">按钮</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      obj:{
        name:"Vue",
        age:7
      }
 
    }
  },
  watch:{
    // obj:{
    //   handler(newVal,oldVal){
    //     // 什么时候执行, obj中一旦有属性发生变化,就会执行这里的代码
    //     console.log("name或者age被修改了",newVal,oldVal);
    //   },
    //   deep:true
    // }

    "obj.age":{
      handler(newVal,oldVal){
        // 什么时候执行, age被修改的时候来执行
        console.log("age被修改了",newVal,oldVal);
      },
    }
  }
}
</script>
 
<style lang = "less" scoped>
  
</style>

注意:

1、如果监听的数据是一个对象,那么 immediate: true失效;

2、一般使用于对引用类型的监听,深度监听,如监听一个Object,只要Object里面的任何一个字段发生变化都会被监听,但是比较消耗性能,根据需求使用,能不用则不用。

3、因为上面代码obj是引用数据类型,val, oldVal指向一致,导致看到的结果一样。


4、deep优化

我们可以通过点语法获取对象中的属性,然后转为字符串,即是对深度监听的优化

<template>
  <div class="home">
    <h3>{{obj.age}}</h3>
    <button @click="btnClick">按钮</button>
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      obj: {
        name: "Lucy",
        age: 13
      }
    };
  },
  methods: {
    btnClick() {
      this.obj.age = 33;
    }
  },
  watch: {
    // 通过点语法获取对象中的属性,然后转为字符串,即是对深度监听的优化
    "obj.age": {
      handler(val, oldVal) {
        console.log(val, oldVal);
      },
      deep: true,
      immediate: true,		// 此时监听的数据不是一个对象,可以使用immediate
    }
  }
};
</script>

5、Watch与Computed的区别

  • watch中的函数是不需要调用的,computed内部的函数调用的时候不需要加()

  • watch(属性监听),监听的是属性的变化,而computed(计算属性),是通过计算而得来的数据

  • watch需要在数据变化时执行异步或开销较大的操作时使用,而对于任何复杂逻辑或一个数据属性,在它所依赖的属性发生变化时,也要发生变化,这种情况下,我们最好使用计算属性computed。

  • computed 属性的结果会被缓存,且computed中的函数必须用return返回最终的结果

  • watch 一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;

6、Watch与Computed的使用场景

  • computed    

    • 当一个结果受多个属性影响的时候就需要用到computed

    • 最典型的例子: 购物车商品结算的时候

  • watch

    • 当一个数据的变化需要有额外操作的时候就需要用watch

    • 搜索数据

  • 总结:

    • 一个值的结果受其他值的影响,用computed

    • 一个值的变化将时刻影响其他值,用watch

;