Vue 的 watch 用法

1,281 阅读1分钟

监听器。若某个属性变化了,就执行相应的操作。
举个栗子:

需求1:点击按钮,控制台输出 "obj.a 变了"

const vm = new Vue({
  data: {
    obj: {
     a:0,
    }
  },
  template: `
    <div>
      <button @click=@click="obj.a+=1">改变 obj.a </button>
      <hr>
    </div>
  `,
  watch: {
    obj:{
      handler(){
        console.log("obj.a 变了")
      }
    }
  }
}).$mount("#app");

点击按钮,却没有出现预期的效果。为什么?
Vue 默认只会监听到 obj 的变化才执行对应的操作,无法监听对象 obj 内部值的变化。

解决办法

  1. 直接监听 obj.a
watch: {
    'obj.a':{
      handler(){
        console.log("obj.a 变了")
      }
    }
  },
  1. 通过** deep **实现

deep 选项

  • 监听对象时是否往深了看
  • 希望监听对象内部值的变化,可以在选项参数中指定 deep: true
  • 默认是 false
watch: {
    obj:{
      handler(){
        console.log("obj.a 变了")
      },
      deep:true
    }
  },

需求2:还未点击按钮,控制台就输出 "obj.a 变了"

即:还未变化就触发 watch,我们可以通过 immediate 实现

immediate 选项

  • 立即以监听的数据的 当前值 触发 watch,还未等到数据变化
  • 即希望页面一渲染就触发 watch,可以在选项参数中指定 immediate: true
  • 默认是 false
watch: {
    obj:{
      handler(){
        console.log("obj.a 变了")
      },
      deep:true,
      immediate: true
    }
  },

注销监听

watch 的另一种写法:实例化时调用 $watch()

vm.$watch('obj', function(){
  console.log("obj.a 变了");
}, {deep: true,immediate: true});

我们可以使用这种方式来取消监听。vm.$watch 返回一个取消观察函数,用来停止触发回调:

const unwatch = vm.$watch('obj', function(){
  console.log("bianh");
}, {deep: true,immediate: true});
unwatch();

watch 与 computed 的区别

computed :是一个计算属性

  • computed 会根据依赖的数据返回新的计算结果,被引用时无需加括号,当作属性使用
  • 虽然我们可以通过调用方法来得到同样的结果。但是每当触发重新渲染时,调用方法将总会再次执行函数。
  • 然而 computed 会根据数据依赖自动缓存,若依赖不变,computed 的值就不会重新计算。即计算属性会立即返回之前的计算结果,而不必再次执行函数

watch : 是一个监听器

  • 如果某个属性发生变化了,就执行一个函数
  • 它有俩个选项
  • deep 选项用来是否要深度监听一个对象,即监听对象里面的东西。
  • immediate 选项表示是否要在第一次渲染就执行函数