VUE 3.0下使用echarts5.1.1,点击legend报错Cannot read property ‘type‘ of undefined

VUE 3.0下使用echarts5.1.1,点击legend报错Cannot read property 'type' of undefined

让我们先来看看报错

bug复现

  1. 点击lenged选择不同的数据条目
    在这里插入图片描述
  2. 报错
    在这里插入图片描述
    3.报错详情
    seriesModel.coordinateSystem为undefined
    在这里插入图片描述

bug解决思路

  1. 首先保持vue版本不变,我将echarts降级为4.7.0版本,同样会有这个报错
  2. 保持ehcarts版本不变,我将vue降级为2.7.1版本,发现这个报错竟然消失了!!
  3. 那么可以得出,我的getOption()和setOption()的代码层面是无误的
  4. 接下来就是去找mounted过程中产生错误的原因

解决

  1. 先看旧代码
    这里在data里定义了myEcharts=null,以至于echarts.init在初始化时是可行的,但是在切换series或者resize时时会报错的
setup(props) {
  const dataMap = reactive({
    showEmpty: false,
    myEcharts:null,
  });
  onMounted(() => {
    const echarts = inject('ec'); //引入
    nextTick(() => {
      dataMap.myEcharts = echarts.init(document.getElementById(props.echartId));
      window.addEventListener('resize', function () {
        dataMap.myEcharts.resize();
      });
      dataMap.myEcharts.clear();
      props.option && dataMap.myEcharts.setOption(props.option, true);
    });
  });
  return {
    dataMap,
  };
},
  1. 新代码
    在onMounted内部定义const myEcharts = echarts.init!!,由于我的id是父组件通过props值传递传给echarts组件的,所以我加上了nextTick方法在下次 DOM 更新循环结束之后执行延迟回调,这样绘制的图表就没有问题了
 setup(props) {
  const dataMap = reactive({
    showEmpty: false,
  });
  onMounted(() => {
    const echarts = inject('ec'); //引入
    nextTick(() => {
      const myEcharts = echarts.init(document.getElementById(props.echartId));
      window.addEventListener('resize', function () {
        myEcharts.resize();
      });
      myEcharts.clear();
      props.option && myEcharts.setOption(props.option, true);
    });
  });
  return {
    dataMap,
  };
},

附上完整代码

<template>
  <div class="echarts">
    <div class="echarts" :id="echartId"></div>
  </div>
</template>

<script>
  import { defineComponent, onMounted, reactive, inject, nextTick, watch } from 'vue';
  export const echartLoadingOptions = { color: '#1890ff', fontSize: 14 };
  export default defineComponent({
    name: 'echart',
    props: {
      option: {
        type: Object,
        default() {
          return {};
        },
      },
      echartId: {
        type: String,
        default: function () {
          return '';
        },
      },
    },
    setup(props) {
      const echarts = inject('ec'); //引入
      const dataMap = reactive({
        showEmpty: false,
      });
      onMounted(() => {
        nextTick(() => {
          const myEcharts = echarts.init(document.getElementById(props.echartId));
          window.addEventListener('resize', function () {
            myEcharts.resize();
          });
          myEcharts.clear();
          props.option && myEcharts.setOption(props.option, true);
          watch(
            () => props.option,
            () => {
              myEcharts.clear();
              props.option && myEcharts.setOption(props.option, true);
            }
          );
        });
      });
      return {
        dataMap,
      };
    },
  });
</script>

<style scoped>
  .echarts {
    width: 100%;
    height: 100%;
  }
</style>

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Vue3.0使用 ECharts,解决图例(legend)事件被外层 div 事件遮挡的问题,可以通过以下步骤实现: 1. 在 Vue3.0使用 ECharts,需要先安装 `echarts` 和 `vue-echarts` 两个依赖: ```bash npm install echarts vue-echarts ``` 2. 在 Vue3.0使用 ECharts,需要在组件中注册 ECharts 组件,并将图表配置项传递给 ECharts 组件: ```vue <template> <div class="chart-container"> <vue-echarts :options="chartOptions" @legend-selectchanged="handleLegendSelect"></vue-echarts> </div> </template> <script> import * as echarts from 'echarts'; import { use } from 'echarts/core'; import { CanvasRenderer } from 'echarts/renderers'; import { LineChart } from 'echarts/charts'; import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'; import VueECharts from 'vue-echarts'; // 注册必要的组件 use([CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent]); export default { components: { VueECharts, }, data() { return { // ECharts 图表配置项 chartOptions: { // ... }, }; }, methods: { // 监听图例的选择事件 handleLegendSelect(params) { console.log(params); }, }, }; </script> ``` 3. 在组件中,为外层 div 元素添加一个事件监听器,并通过判断事件的 target 是否为图例元素来决定是否处理该事件: ```vue <template> <div class="chart-container" @click="handleContainerClick"> <vue-echarts :options="chartOptions" @legend-selectchanged="handleLegendSelect"></vue-echarts> </div> </template> <script> import * as echarts from 'echarts'; import { use } from 'echarts/core'; import { CanvasRenderer } from 'echarts/renderers'; import { LineChart } from 'echarts/charts'; import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'; import VueECharts from 'vue-echarts'; // 注册必要的组件 use([CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent]); export default { components: { VueECharts, }, data() { return { // ECharts 图表配置项 chartOptions: { // ... }, }; }, methods: { // 监听图例的选择事件 handleLegendSelect(params) { console.log(params); }, // 监听外层 div 的点击事件 handleContainerClick(event) { if (event.target.tagName === 'SPAN' && event.target.className.indexOf('ec-legend-item') >= 0) { // 如果点击的是图例元素,则处理该事件 event.stopPropagation(); this.$refs.chart.dispatchAction({ type: 'legendToggleSelect', name: event.target.innerText, }); } }, }, }; </script> ``` 在上述代码中,我们为外层 div 元素添加了一个 `@click` 事件监听器,并在事件处理函数中判断事件的 target 是否为图例元素。如果是,则处理该事件,并通过 `$refs.chart` 获取到 ECharts 实例,调用 `dispatchAction` 方法来触发图例的展示或隐藏。同时,我们在处理事件时调用了 `event.stopPropagation` 方法来阻止事件冒泡到外层 div,从而避免了被遮挡的问题。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值