前言
最近做的一个页面跳转碰到一个问题就是我点击跳转的第一次没有传到值,再点击第二次的时候才有值,很是奇怪,研究了一下watch
的一些相关属性。
immediate属性
发现watch
的一个特点是最初绑定的时候不执行改变即第一次直接赋值不会监听到,这里需要用到immediate
属性,默认值为false
,我们需要这样写immediate:true
,即立刻执行。
deep属性
watch
的另一个属性是deep
,默认值为false
,代表是否深度监听,设置deep:true
,意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样开销性能就会非常大了,任何修改对象里面的一个属性都会触发这个监听器里的handler
。优化方法就是像我下面的代码一样使用字符串形式监听。
注销watch
为什么要注销watch
?因为我们的组件是经常要被销毁的,比如我们跳一个路由,从一个页面跳到另外一个页面,那么原来的页面的watch
其实就没用了,这时候我们应该注销掉原来页面的watch
的,不然的话可能会导致内置溢出。好在我们平时watch
都是写在组件的选项中的,他会随着组件的销毁而销毁。
const app = new Vue({
template:'',
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
由于我这个currentNavigation
是写在store.js
里的,所以在页面时需要计算赋值给它。
实现代码:
#store.js
currentNavigation: { // 当前页面信息
name: '首页',
id: 'home',
componentName: 'appHome'
},
#页面.vue
computed: {
currentNavigation () {
return this.$store.state.currentNavigation
}
},
watch: {
'currentNavigation.param': {
immediate: true,
deep: true,
handler (val, oldVal) {
if (!Utils.isEmptyData(val) && oldVal !== val) {
this.handleRouteParam() // 处理路由跳转后的页面渲染数据
}
}
}
}