_
2023/5/11 18:36:461850

今天我们主要学习vue的监听器watch,它的作用是可以用来监听data中某个值的变化,然后来做一些逻辑处理,看起来和我上节课学的computed计算属性功能相似,但实则又有所不同,那么我们就一起来看一下,监听器怎么来使用。

Watch监听器的使用

老样子还是先来复制一下hello world 基础代码,我们先来声明一个count变量,然后在data下面写一个watch它也是一个对象,在里面我们可以来监听一下count,当count的值发生变化的时候它就会执行这个函数,打印出"count changed")。

watch:{
   count(){
     console.log("count changed")
   }
 },

咱们可以来看一下效果,在调试工具中我们来输出尝试修改一下count,这个时候就会打印出 "count changed"。

监听器的方法中还可以接收两个参数,第一个参数是current(当前的值) , 第二个参数是prev(变化之前的值)。我们可以都打印出来给看一下。

watch:{
      count(current,prev){
        console.log("count changed")
        console.log("当前的值:",current)
        console.log("变化前的值:",prev)
      }
    },

打印结果:

一个简单例子

我们来做一个简单的例子,我们再来声明一个price单价,我们需求是希望count 发生改变的时候自动计算出 count(数量)*price(单价)的总价。那么我们在来声明一个total 用接收我们的计算结果,然后把total 插入到模版里面。

计算属性和监听器的区别

其实同样的需求,我们使用computed也是能够实现的 包括使用methods也是可以实现的,那么它们什么区别呢,methods上节课我们已经说过了,这次我们只来比较一下watch和computed。

我们先来演示一下怎么使用computed计算属性来完成同样的需求。

<script>
  const app = Vue.createApp({
    data() {
      return {
        count:2,
        price:10,
        total:20,
        message:"hello world"
      }
    },
    watch:{
      count(current,prev){
        // console.log("count changed")
        // console.log("当前的值:",current)
        // console.log("变化前的值:",prev)
        this.total = current * this.price
      }
    },
    computed:{
      newTotal(){
        return this.count * this.price
      }
    },
    template: `
      <div>{{newTotal}}</div>
    `
  })
  const vm = app.mount("#app")
</script>
watch和computed的区别:

1.计算属性computed必须要返回一个值,并且默认执行一次计算逻辑,而watch只有监听的数据发生变化时才会执行,也就是说数据没有变化,它是不执行里边业务逻辑的。

我们可以来做一下简单的验证。我们total的默认值改成0。

然后我们分别把watch执行的结果和computed执行的结果都打印到界面观察一下。

然后我们看一下运行结果

第一个20 就是我们computed 已经计算得到结果,而第二个0就是我们total的默认结果,它还没有被计算过,因为它需要count发生变化之后才会执行计算得到结果。

2.watch 支持异步执行 而 computed 不支持异步执行

我们可以使用timeout来模拟一个异步执行。

 watch:{
      count(current,prev){
        setTimeout(()=>{
          console.log("watch")
          this.total = current * this.price
        },3000)

      }
    },
    computed:{
      newTotal(){
        let total = 0
        setTimeout(()=>{
          console.log("computed")
          total=this.count * this.price
        },3000)
        return total
      }
    },

看一下效果我们 我们界面显示了两个 0 0 说明computed并没有返回出我们已经计算好的值,而watch是因为需要监听的改变了才会执行。我们来修改一下count 这样就能够看到效果了 watch可以延迟了3秒钟打印出结果。

3.computed 可以依赖多个值 而 watch值可以监听一个值

我们在computed不是使用了两个变量吗, 那么它就可以同时依赖这两个值,只要有一个依赖值变化它都会触发计算逻辑。

computed:{
      newTotal(){
        return this.count * this.price
      }
    },

4.computed有缓存机制(这个特性上节课忘记和大家说了)

什么叫缓存呢,就是computed执行计算逻辑之后会把计算好的结果放到缓存,页面渲染时它会重新执行计算逻辑而是去读取缓存。

建议

  • 如果一个数据需要经过复杂计算就用 computed 因为它有缓存 不会执行无意义的重复逻辑
  • 同一个需求使用computed watch 和 methods都实现的选择computed它会更简单 性能会更好。
  • 当需要监听多个值的时候,建议使用computed。
  • 当需要执行异步操作的时候就用 watch。
视频讲解