Vue.js同时监听多个数据时如何判断监听回调全部执行完成
多数据联合监听批量赋值完成时机识别方案
现有计算属性返回多属性组合对象+deep深度监听的写法,单属性变更时可以正常触发回调,但接口批量赋值场景下,受Vue响应式更新队列机制影响,watch会随赋值操作多次触发,无法直接定位所有回调执行完成的节点,直接用以下方案解决即可:
方案1:标记位 +
$nextTick(无需改动现有监听逻辑,改造成本最低)
Vue的更新队列基于微任务实现,同一轮同步操作触发的所有watch回调、视图更新都会在当前宏任务末尾的微任务阶段全部执行完成,配合批量赋值标记位就能精准拿到执行结束的节点:- 先在data中新增标记位:
data() { return { isBatchAssigning: false, // 其余原有数据 } }- 改造接口赋值逻辑:
async getListData() { this.isBatchAssigning = true const res = await requestApi() // 同步给所有被监听属性赋值,不要加await/setTimeout这类异步操作打断 this.propA = res.data.propA this.propB = res.data.propB // 等当前轮次所有watch回调跑完 this.$nextTick(() => { this.isBatchAssigning = false // 这里直接写所有监听执行完要跑的后续业务代码 handleAfterAllWatchFinished() }) }- 可选优化:在原有watch的handler里加判断,跳过批量赋值阶段的重复执行,减少性能浪费:
changeData: { handler(val) { if (this.isBatchAssigning) return // 原有的单属性变更时要执行的逻辑 }, deep: true }方案2:优化联合监听实现,减少无效触发
现在用计算属性返回对象+开deep的写法本身有额外的性能开销,完全可以简化:把计算属性的返回值改成存监听值的数组,watch配置去掉deep,一样能实现多属性联合监听,触发逻辑更可控,不会出现意外的多余触发:// 改造计算属性 changeData() { return [this.propA, this.propB] }, // 改造watch changeData: { handler([propA, propB]) { // 原有业务逻辑 } }这种写法下批量赋值场景配合
$nextTick,同样可以精准拿到所有回调执行完成的时机。
注意事项:不要在watch的handler里无终止条件地修改propA、propB这类被监听的属性,否则会触发循环更新,直接导致时机判断失效。如果业务必须在handler里修改监听值,一定要加判断条件打断循环。
内容的提问来源于stack exchange,提问作者Harinath R
相关产品推荐
相关产品推荐

