这两天遇到个奇奇怪怪的问题

使用Echarts时,正常的操作流程就是

let myChart = this.$echarts.init(document.getElementById('divid'))
let option={...}
myChart.setOption(option)

需要刷新数据时把option的数据源用接口赋值重复调用上面的方法就行

一直这样用也没出什么问题,但是昨天新做了个图,结果第一次渲染没问题,二次渲染时,在调用setOption的时候一直报 Cannot read property ‘id‘ of undefined” ,检查了代码,各种属性值都是正常赋值,就很奇怪

在网上找了找解决方案,只有一个有用 就是 

myChart.setOption(option,true)


将第二个参数设置为true ,这个参数代表合并模式为 普通合并还是 替换合并

组件合并模式

对于一种类型的组件(如:xAxisseries):

  • 如果设置opts.notMergetrue,那么旧的组件会被完全移除,新的组件会根据option创建。
  • 如果设置opts.notMergefalse,或者没有设置 opts.notMerge
  • 如果在opts.replaceMerge里指定组件类型,这类组件会进行替换合并
  • 否则,会进行普通合并

什么是普通合并替换合并

普通合并

对于一种类型的组件(如:xAxisseries),新来的 option 中的每个“组件描述”(如:{type: 'xAxis', id: 'xx', name: 'kk', ...})会被尽量合并到已存在的组件中。剩余的情况,会在组件列表尾部创建新的组件。整体规则细节如下:

  • 先依次对 option 中每个有声明 id 或者 name 的“组件描述”,寻找能匹配其 id 或者 name 的已有的组件,找到的话则合并。
  • 再依次对 option 中剩余的“组件描述”,寻找还未执行过前一条的已有组件,找到的话则合并。
  • 其他 option 中剩余的“组件描述”,用于在组件列表尾部创建新组件。

特点:

  • 永远不会删除已存在的组件。也就是说,只支持增加,或者更新组件。
  • 组件的索引(componentIndex)永远不会改变。
  • 如果 id 和 name 没有在 option 中被指定(这是经常出现的情况),组件会按照它在 option 中的顺序一一合并到已有组件中。这种设定比较符合直觉。 

替换合并

对于一种类型的组件(如:xAxisseries),只有 option 中指定了 id 并且已有组件中有此 id 时,已有组件会和 option 相应组件描述进行合并。否则,已有组件都会删除,新组件会被根据 option 创建。细节规则如下:

  • 先依次对 option 中每个有声明 id 的“组件描述”,寻找能匹配其 id 或者 name 的已有的组件,找到的话则合并。
  • 删除其他没匹配到的已有组件。
  • 依次对 option 中剩余的“组件描述”,创建新组件,填入刚因删除而空出来的位置上,或者增加到末尾。

特点:

  • 与 普通合并 相比,支持了组件删除。
  • 已有组件的索引永远不会变。这是为了保证,option 或者 API 中的 index 引用(例如:xAxisIndex: 2)仍能正常一致得使用。
  • 整个处理过程结束后,可能存在一些“洞”,也就是说,在组件列表中的某些 index 上,并没有组件存在(被删除了)。但是这是可以被开发者预期和控制的。

简单来说就是 该参数为false时,渲染组件时只会新增和更新,为true时还会将无用的组件删除并更新索引

而产生本文问题的原因应该就是在这个索引遍历上

ResizeObserver 会导致echarts 没有动画_echarts

 可以看到报错的点是在一个forEach中某个id未声明导致的,也就是存在了某个无效组件,但进入了组件匹配中导致了报错