更多文章可戳:github.com/MagicalBrid…html
假设有以下代码:git
<div>
<p>FullName: {{fullName}}</p>
<p>FirstName:
<input type="text" v-model="firstName">
</p>
</div>
复制代码
new Vue({
el: '#root',
data: {
firstName: 'Dawei',
lastName: 'Lou',
fullName: ''
},
watch: {
firstName(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
}
}
})
复制代码
上面的代码的效果是,当咱们输入firstName
后,watch
监听每次修改变化的新值,而后计算出fullName
。github
这里watch
的一个特色是,最初绑定的时候是不会执行的,要等到firstName
改变的时候才执行监听计算,那咱们想要一开始就让他最初绑定的时候就执行怎么办呢?咱们须要修改一下咱们的watch
写法,修改事后的watch
代码以下:app
watch:{
firstName:{
handler(newName,oldName){
this.fullName = newName+ ' ' + this.lastName
},
// 表明watch里面声明了firstName这个方法以后当即执行handler方法
immediate: true
},
}
复制代码
注意到handler了吗?咱们给firstName
绑定了一个handler方法,以前咱们写的watch
方法其实默认写的就是这个handler,Vue.js会处理这个逻辑,最终编译出来的其实就是这个handler.函数
而immediate:true 表明若是在watch
里面声明了firstName
以后,就会当即先去执行里面的handler方法,若是为false,就和咱们以前的效果同样,不会再绑定的时候就执行。性能
watch
里面还有一个属性deep,默认值是 false 表明的是否深度监听,好比咱们data里面有一个obj属性。优化
<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: 123
}
},
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true
}
}
})
复制代码
当咱们在输入框中输入数据改变obj.a数据的时候。咱们发现虽然视图更新了,可是在handler回调并无执行,也就没有打印obj.a changed
在这里Vue并不能检测到对象的属性的添加或者删除。因为Vue在初始化的时候对于属性执行了getter/setter转化过程,因此属性必须在data对象上存在才能让Vue转换它,这样才能让它是响应式的。ui
默认的状况下,handle只监听obj这个属性它的引用的变化,咱们值有给obj赋值的时候它才会监听到,好比咱们在mounted事件钩子函数中对obj进行从新赋值。这个时候 是能够触发 handler 监听回调的。this
若是咱们想要监听 obj 里的属性a的值呢? 这个时候 deep 属性就派上用场了!spa
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
deep:true
}
}
复制代码
deep的意思是深刻观察,监听器会一层层的往下遍历,给对象的全部的属性都添加这个侦听器,可是 这样性能开销就会比较大了,任何修改obj里面任何一个属性都会触发这个侦听器里面的handler.
优化,咱们可使用字符串形式进行监听。
watch:{
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true
}
}
复制代码
使用上述的写法,即便不使用deep属性选项,依然可以成功的触发监听回调。
为何要注销watch
? 由于咱们的组件是常常要销毁的,好比咱们跳转一个路由,从一个页面跳转另外一个页面。那么原来的页面的watch
就没有用了,这个时候咱们应该注销原来页面的watch
否则会有一些性能问题,好在咱们平时都是将watch
写在组件中的,他会随着组件的销毁而销毁。
const app = new Vue({
template: '<div id="root">{{text}}</div>',
data: {
text: 0
},
watch: {
text(newVal, oldVal){
console.log(`${newVal} : ${oldVal}`);
}
}
});
复制代码
可是,若是咱们使用下面这样的方式写 watch,那么就要手动注销了,这种注销其实也很简单
const unWatch = app.$watch('text', (newVal, oldVal) => {
console.log(`${newVal} : ${oldVal}`);
})
unWatch(); // 手动注销watch
复制代码
app.$watch调用后会返回一个值,就是unWatch
方法,你要注销 watch
只要调用unWatch
方法就能够了。
最后谢谢各位小伙伴愿意花费宝贵的时间阅读本文,若是本文给了您一点帮助或者是启发,请不要吝啬你的赞和Star,您的确定是我前进的最大动力。github.com/MagicalBrid…