Vue watch选项

定义

watch 选项是一个对象,键是需要观察的表达式,值是对应回调函数。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。

用法

watch 对象里的 value 是对应的回调函数

data () {
  return {
    a: 1
  }
},
watch: {
  a: function (newVal, oldVal) {
    console.log(newVal, oldVal)
    // 2 1
  }
},
created () {
  this.a = 2
}
复制代码

a 的值被改变时,watch 对象中 a 所对应的函数会被调用,该函数接收两个参数,第一个为 a 的 new value,第二个为 a 的 old value。

value 也可以是方法名

data () {
  return {
    a: 1
  }
},
watch: {
  a: 'foo'
},
created () {
  this.a = 2
},
methods: {
  foo (newVal, oldVal) {
    console.log(newVal, oldVal)
    // 2 1
  }
}
复制代码

a 的值被改变时,会直接触发 methods 里的 foo 方法,该方法同样接收新值和旧值两个参数。

深度监听

对象内部属性或方法发生改变,须使用深度监听模式才能监听到该对象的改变

data () {
  return {
    box: {
      name: 'jordan'
    }
  }
},
watch: {
  box: {
    handler: function (newVal, oldVal) {
      console.log(newVal.name, oldVal.name)
      // kobe kobe
    },
    deep: true  // 深度监听模式
  }
},
created () {
  this.box.name = 'kobe'
}
复制代码

运行代码会打印出 kobe kobe,这是因为 box.name 的值更新之后, box 对象的内存地址仍然不变,newValoldVal 都指向该地址,值更新触发 handler 之后打印出两个更新之后的 name,即 'kobe kobe'

如果去掉 deep: true 将无法监听到 box 的变化,除非直接给 this.box 赋值,改变 box 指针的指向,这种方式也能拿到 old valuenew value,对应 this.box 指针前后分别指向的 box 对象。

不使用深度监听时,可以直接监听 box.name

data () {
  return {
    box: {
      name: 'jordan'
    }
  }
},
watch: {
  'box.name': {
    handler: function (newVal, oldVal) {
      console.log(newVal, oldVal)
      // kobe jordan
    }
  }
},
created () {
  this.box.name = 'kobe'
}
复制代码

这时 box.name 又是一个简单值,所以输出 'kobe jordan'

数组的监听

data () {
  return {
    box: [1, 1, 1]
  }
},
watch: {
  box: {
    handler: function () {
      console.log('watch works')
    }
  }
},
created () {
  this.box[0] = 2
  this.box.length = 4
  this.box.push(1)  // watch works
  this.box.splice(0, 1, 2)  // watch works
}
复制代码

created 里使用了4种方式对 box 进行操作,第一种和第二种方式 watch 是监听不到的,即便使用深度监听模式也无法监听的到,可以参考下这里

使用 immediate

data () {
  return {
    box: 1
  }
},
watch: {
  box: {
    handler: function () {
      console.log('watch works')
    },
    immediate: true
  }
}

// watch works
复制代码

增加 immediate: true 选项,handler 会在侦听开始之后被立即调用,即便 box 的值没有改变。如果对 this.box 的值加以修改,便会输出两次 'watch works',一次是侦听开始的时候,一次是 box 的值被修改的时候。

watch 里的 value 可以是放在一个数组里面的多个 handler

data () {
  return {
    box: 1
  }
},
watch: {
  box: [
    function foo (newVal, oldVal) {
      console.log(newVal, oldVal)
      // 2 1
    },
    function bar (newVal, oldVal) {
      console.log(newVal, oldVal)
      // 2 1
    }
  ]
},
created () {
  this.box = 2
}
复制代码

每一个 handler 都可以接收 new valueold value 两个参数,并且会按各自在数组中的顺序先后触发。当然下面的操作也能实现这样的场景。

data () {
  return {
    box: 1
  }
},
watch: {
  box: function (newVal, oldVal) {
    this.foo(newVal, oldVal)
    this.bar(newVal, oldVal)
  }
},
created () {
  this.box = 2
},
methods: {
  foo (newVal, oldVal) {
    console.log(newVal, oldVal)
  },
  bar (newVal, oldVal) {
    console.log(newVal, oldVal)
  }
}
复制代码

不应该使用箭头函数来定义 watcher 函数

data () {
  return {
    box: 1
  }
},
watch: {
  box: newVal => {
    this.updateBox(newVal)
  }
},
created () {
  this.box = 2
},
methods: {
  updateBox (newVal) {
    this.box = newVal
  }
}
复制代码

上面的例子会报错,是因为箭头函数绑定了父级作用域的上下文,所以 this 将不会指向 Vue 实例,也就没有 this.updateBox 这个方法,可以参考ES6箭头函数 this指向

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值