Vue watch选项
watch 的用法
watch 对象里的 value 是对应的回调函数
data () { return { a: 1 } }, watch: { a: function (newVal, oldVal) { console.log(newVal, oldVal) // 2 1 } }, created () { this.a = 2 }
value 也可以是方法名
data () { return { a: 1 } }, watch: { a: 'foo' }, created () { this.a = 2 }, methods: { foo (newVal, oldVal) { console.log(newVal, oldVal) // 2 1 } }
深度监听
对象内部属性或方法发生改变,须使用深度监听模式才能监听到该对象的改变
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' }
不使用深度监听时,可以直接监听 xxx.name
data () { return { box: { name: 'jordan' } } }, watch: { 'box.name': { handler: function (newVal, oldVal) { console.log(newVal, oldVal) // kobe jordan } } }, created () { this.box.name = 'lalala' }
// 这时box.name
又是一个简单值,所以输出'lalala 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
是监听不到的,即便使用深度监听模式也无法监听的到,可以参考 https://cn.vuejs.org/v2/guide/list.html#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9
使用 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 value
和old 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的指向