Nuxtjs/Vuejs监听Vuex的Watchers因值变更触发死循环如何解决
解决方案
问题核心原因
死循环是双向watch的连锁触发导致的:
- 修改XML内容触发XML的watcher,转换失败后给JSON赋值错误信息
- JSON内容变更触发JSON的watcher,转换错误信息失败后又给XML赋值错误信息
- 两者循环触发,最终两边都被覆盖成错误内容
可行修复方案
方案1:加转换锁变量(最稳妥,无需修改现有绑定逻辑)
在组件内加一个共享的布尔锁变量,转换执行期间锁死,避免反向watch触发,同时转换失败时仅修改目标字段,保留源字段的用户输入内容:
<script> export default { data() { return { // 转换锁,true表示当前正在执行转换逻辑 isConverting: false } }, computed: { xmlContent: { get() { return this.$store.state.xmlContent }, set(val) { this.$store.commit('SET_XML_CONTENT', val) } }, jsonContent: { get() { return this.$store.state.jsonContent }, set(val) { this.$store.commit('SET_JSON_CONTENT', val) } } }, watch: { // 监听XML变更转JSON async xmlContent(newXml) { // 转换期间直接跳过,避免循环触发 if (this.isConverting) return this.isConverting = true try { const jsonResult = yourXmlToJsonConvertFunc(newXml) this.jsonContent = jsonResult } catch (err) { // 转换失败仅修改JSON内容,不改动XML的用户输入 this.jsonContent = `XML格式错误:${err.message}` } finally { // 等待DOM更新完成后再释放锁 await this.$nextTick() this.isConverting = false } }, // 监听JSON变更转XML async jsonContent(newJson) { if (this.isConverting) return this.isConverting = true try { const xmlResult = yourJsonToXmlConvertFunc(newJson) this.xmlContent = xmlResult } catch (err) { // 转换失败仅修改XML内容,不改动JSON的用户输入 this.xmlContent = `JSON格式错误:${err.message}` } finally { await this.$nextTick() this.isConverting = false } } } } </script>
方案2:调整转换失败的赋值逻辑
如果不想加锁,也可以直接限定:仅转换成功的时候才修改反向字段,转换失败的时候仅给目标字段赋值错误提示,绝不修改源输入字段,也能避免循环触发。
内容的提问来源于stack exchange,提问作者BATMAN_2008
相关产品推荐
相关产品推荐

