Vue——watch选项详解
1. 什么是watch选项?(官方解释)类型:{ [key: string]: string | Function | Object | Array }详细:一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例i化时调用 $watch(),遍历 watch 对象的每一个属性。2. 通俗解释watch选项能够监听值的变化。3...
·
1. 什么是watch选项?(官方解释)
- 类型:{ [key: string]: string | Function | Object | Array }
- 详细:一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例i化时调用 $watch(),遍历 watch 对象的每一个属性。
2. 通俗解释
- watch选项能够监听值的变化。
3. 简单使用
<div>
<p>Number: {{ myNumber }}</p>
<p>Number: <input type="text" v-model.number="myNumber"></p>
</div>
new Vue({
el: '#root',
data: {
myNumber: 'Dawei'
},
watch: {
myNumber(newVal, oldVal) {
console.log('newVal', newVal);
console.log('oldVal', oldVal);
}
}
})
根据上面的代码,在输入框输入内容,控制台会显示新值还有旧值。
4. handler方法和immediate属性
根据上面的例子我们加以改造
<div>
<p>Number: {{ myNumber }}</p>
<p>Number: <input type="text" v-model.number="myNumber"></p>
</div>
new Vue({
el: '#root',
data: {
myNumber: 'Dawei'
},
watch: {
myNumber: {
handler(newVal, oldVal) {
console.log('newVal', newVal);
console.log('oldVal', oldVal);
},
immediate: true
}
}
})
- handler方法就是你watch中需要具体执行的方法;
- immediate为true时则立即触发回调函数;如果为false,则和上面的例子一样,不会立即执行回调。
5. deep属性
上面两个例子都是监听简单数据类型的数据,对于对象或者对象中的属性,我们如何监听?那么就介绍deep属性。它的作用就是解决这个问题的关键。
<div>
<p>Obj-a: {{ obj.a }}</p>
<p>Obj-a: <input type="text" v-model="obj.a"></p>
</div>
new Vue({
el: '#root',
data: {
obj: {
a: ''
}
},
watch: {
'obj': {
handler(newVal, oldVal) {
console.log('newVal-obj.a', obj.a);
console.log('oldVal-obj.b', obj.a);
},
deep: true
}
}
})
deep顾名思义就是深入监听,也就是在对象中层层遍历,并在监听对象上的每一个属性上都添加监听,固然也会损耗性能。
6. 注销监听
在第五点后面我提到了损耗性能,但对于组件开发的情况下是不存在,监听事件会随着组件的销毁而销毁。而在组件外声明的监听事件,我们需要使用unWatch方法注销,防止内存溢出。
7. 监听的多种写法(只介绍常用的两种)
// 第一种
<div>
<p>Obj-a: {{ obj.a }}</p>
<p>Obj-a: <input type="text" v-model="obj.a"></p>
</div>
new Vue({
el: '#root',
data: {
obj: {
a: ''
}
},
watch: {
obj: { // <--重点看这里
handler(newVal, oldVal) {
console.log('newVal-obj.a', obj.a);
console.log('oldVal-obj.b', obj.a);
},
deep: true
}
}
})
// 第二种
<div>
<p>Obj--a: {{ obj.a }}</p>
<p>Obj--a: <input type="text" v-model="obj.a"></p>
</div>
new Vue({
el: '#root',
data: {
obj: {
a: ''
}
},
watch: {
'obj.a': { // <--重点看这里
handler(newVal, oldVal) {
console.log('newVal-obj.a', obj.a);
console.log('oldVal-obj.b', obj.a);
},
deep: true
}
}
})
8. 特别注意
- ES6中推出了箭头函数,上述例子我均未使用箭头函数,如果在handler函数中使用了箭头函数,改变了this指向,就无法获取到Vue实例,则为undifined。
- 对于父子组件传参,异步获取数据有时会存在获取不到值的情况。这时候watch就派上用场,适当的时候要配合immediate或者deep属性配合使用。
9. 源码解析
// state.js
function createWatcher (
vm: Component,
expOrFn: string | Function,
handler: any,
options?: Object
) {
if (isPlainObject(handler)) {
options = handler
handler = handler.handler
}
if (typeof handler === 'string') {
handler = vm[handler]
}
return vm.$watch(expOrFn, handler, options)
}
Vue的类初始化建立数据绑定时,会从用户传的参数来判断拿什么来做监听的数据变量,拿什么来当作监听到数据变更后的处理函数。因为在变量你传了一个对象,这个对象就是createWatcher函数参数中对应的handler,函数第一步逻辑就是判断它是不是一个对象,如果是对象,就拿它里面的handler参数来作为监听事件的处理函数。
更多推荐
已为社区贡献1条内容
所有评论(0)