Vue 3修改带响应式配置的ApexCharts选项触发过多递归错误
Vue 3 + ApexCharts 响应式配置引发递归溢出问题解决
问题现象
在Vue 3.2.13配合ApexCharts 3.53.0时,只要图表配置中包含responsive数组:
- 无论是直接替换整个
optionsData对象,还是调用$refs.myApex.updateOptions()修改配置,都会触发too much recursion递归错误,图表直接消失 - 直接修改
this.optionsData.colors这类属性无任何响应 - 移除
responsive配置后,所有操作恢复正常
错误栈指向Vue响应式模块与ApexCharts内部代码的递归调用:
Uncaught runtime errors: ERROR too much recursion ownKeys@webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:1040:5 value@webpack-internal:///./node_modules/apexcharts/dist/apexcharts.common.js:5:7558 value@webpack-internal:///./node_modules/apexcharts/dist/apexcharts.common.js:5:7592 ...(重复递归调用)
触发场景代码
模板代码:
<apexchart ref="myApex" class="chart" height="100%" type="line" :options="optionsData" :series="seriesData"></apexchart>
脚本代码:
methods: { updateOptionsData() { this.optionsData = { chart: { id: this.chartId, height: '100%', }, responsive: [ { breakpoint: 768, options: { tooltip: { enabled: false, }, }, }, ], }; }, }, mounted() { this.updateOptionsData(); setTimeout( () => { console.log(237); this.optionsData = { ...this.optionsData, colors: ['#000000', '#666666', '#AAAAAA', '#FFFFFF'], }; console.log(238); }, 5000, ); },
调用updateOptions同样触发错误:
this.$refs.myApex.updateOptions({ colors: ['#000000', '#666666', '#AAAAAA', '#FFFFFF'], });
原因分析
Vue 3的响应式系统会对传入的配置对象进行深度代理,而ApexCharts在处理responsive配置时会深度遍历、修改该对象,二者的属性拦截逻辑叠加,引发无限递归调用。
解决方案
方案1:冻结响应式配置对象
用Object.freeze()冻结responsive数组或内部对象,让Vue跳过对其的响应式代理:
updateOptionsData() { this.optionsData = { chart: { id: this.chartId, height: '100%', }, responsive: Object.freeze([ { breakpoint: 768, options: Object.freeze({ tooltip: { enabled: false, }, }), }, ]), }; }
方案2:标记配置为非响应式
使用Vue的markRaw()方法,将整个配置对象标记为永远不转为响应式,避免响应式系统干扰第三方库的内部处理:
import { markRaw } from 'vue'; // ... updateOptionsData() { this.optionsData = markRaw({ chart: { id: this.chartId, height: '100%', }, responsive: [ { breakpoint: 768, options: { tooltip: { enabled: false, }, }, }, ], }); } // 更新颜色时同样用markRaw包裹 setTimeout(() => { this.optionsData = markRaw({ ...this.optionsData, colors: ['#000000', '#666666', '#AAAAAA', '#FFFFFF'], }); }, 5000);
方案3:升级ApexCharts版本
该递归问题在ApexCharts 3.55.0及以上版本中已被官方修复,直接升级依赖即可解决。
补充说明
直接修改this.optionsData.colors无效果,是因为Vue响应式系统无法检测到对象新增属性的变化(原配置对象初始没有colors属性),必须通过替换整个对象的方式触发响应式更新。
内容的提问来源于stack exchange,提问作者SimonMayer
相关产品推荐
相关产品推荐

