问题
watch: {
isAuthenticated: function(val, oldVal) {
for (const key of Object.keys(this.modelSearch)) {
if (key !== 'authentication') {
this.modelSearch[key] = ''
} else {
this.modelSearch[key] = val
}
}
this.handleSearch()
},
...//此处省略其他watch
},
methods:{
async handleSearch() {
try {
await this.$refs.formSearch.validate()
} catch (e) {
return
}
this.pagination.current = 1
this.tableReload(this.formSearch)
},
...//此处省略其他methods
}
在项目中有个tab页切换刷新不同列表的需求,列表其实是同一个组件,刷新不同列表数据可以通过传参进行,即组件的props。上述代码就是监听组件的props值,在监听中实现同步刷新列表数据,即handleSearch。
但是这样的实现,一开始是没有问题的,但是如果在组件中有一开始就加载数据的情况,比如:
mounted: function() {
this.tableReload(this.formSearch)
}
那么情况就会变得有点不一样了,当首次加载组件渲染的时候,会调用两次tableReload,这不是我们不期望的现象,我们期望组件首次加载渲染只调用一次,而tab页切换的时候,我们才再次调用一次。
解决
解决方式如下:
watch: {
isAuthenticated: function(val, oldVal) {
this.modelSearch.authentication = val
},
...//此处省略其他watch
}
总结
这个问题产生的源头,就是我们一开始的watch,我们在watch里本该监听变化来赋值,而多做了刷新列表。刷新列表本来就是在tab页切换的时候发生,我们应该在tab页点击的时候来刷新列表。也就是说,代码封装要按照逻辑进行分拆,属于哪个阶段的事情,就在哪个阶段去解决,而不要通过顺便解决的逻辑,不要利用副作用,要正面作用。上面的情况就是,我们想监听props的值,来顺便刷新列表,但是刷新列表可以不在这个阶段做,只是我们顺便实现了。顺便导致的问题,就是后面如果有新的逻辑,就会乱套。