Echarts图表的二次封装,再也不用每次都写一遍初始化图表了,(Vue3+Ts+Echarts)

Echarts图表的二次封装
我们在做大屏可视化项目的时候,每次都要去声明一个变量,然后init这个图表,然后有变更,又去setOption,假如一个页面有10个图表,我们就要重复去操作10次,那么有没有可能去封装一个Echarts,我们只需要传相关的options进去,他就会自动帮我们做这些操作呢
先给大家封装了之后,使用起来多么的简单
<template>
  <div class="caseContent">
    <Echarts :options="options" v-if="data.length !== 0" />
    <a-empty v-else />
  </div>
</template>
<script setup lang="ts">
  import { computed } from 'vue';
  import Echarts from './common/echarts.vue';
  // 这里编写你需要的options
  const options = computed(() => {
      return xxxxx
  })
</script>
代码是不是特别简洁,而且外部options变化了之后,里面的组件会自动执行setOption来更新图表。
下面我们就来看看如何封装这个Echarts图表吧
<template>
  <div ref="chartRef" :style="{ width: chartWidth, height: chartHeight }"> </div>
</template>

<script setup lang="ts">
  import { onMounted, onBeforeUnmount, onUpdated, ref, watch } from 'vue';
  import * as echarts from 'echarts';

  const props = defineProps({
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    },
    options: {
      type: Object,
      required: true
    }
  });

  // 图表实例引用
  let myCharts = null;

  // 图表容器引用
  const chartRef = ref();
  // 图表宽度和高度
  const chartWidth = ref(props.width);
  const chartHeight = ref(props.height);

  // 初始化图表
  function initChart() {
    if (!myCharts) {
      myCharts = echarts.init(chartRef.value);
      myCharts.setOption(props.options);
    } else {
      updateChart();
    }
  }

  // 更新图表
  function updateChart() {
    if (myCharts) {
      myCharts.setOption(props.options);
    }
  }

  // 观察 options 的变化
  watch(
    () => props.options,
    () => {
      updateChart();
    },
    { deep: true }
  );

  // 生命周期钩子
  onMounted(() => {
    initChart();
  });

  onUpdated(() => {
    if (myCharts) {
      myCharts.resize();
    }
  });

  onBeforeUnmount(() => {
    if (myCharts) {
      // 释放资源,帮助垃圾处理回收机制回收多余内存
      myCharts.dispose();
    }
  });
</script>

<style scoped lang="less">
  /* 可以在这里添加图表容器的样式 */
</style>

给大家举个例子,接口数据,可以自行mock
<template>
  <div class="caseContent">
    <Echarts :options="options" v-if="data.length !== 0" />
    <a-empty v-else />
  </div>
</template>
<script setup lang="ts">
  import { computed } from 'vue';
  import Echarts from './common/echarts.vue';
  // 这里编写你需要的options
  const data = ref([]);
  const options = computed(() => {
    return {
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'line',
          crossStyle: {
            color: '#999'
          },
          label: {
            backgroundColor: '#6a7985'
          }
        },
        formatter: '{b} : {c}'
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        show: true,
        axisLabel: {
          // 设置标签颜色
          textStyle: {
            color: '#fff' // 橙色
          }
        },
        axisTick: {
          show: false
        },
        data: data.value.map((item) => {
          return item.report_time;
        })
      },
      yAxis: {
        type: 'value',
        splitLine: {
          show: false
        },
        axisLabel: {
          // 设置标签颜色
          textStyle: {
            color: '#fff' // 橙色
          }
        },
        minInterval: 1
      },
      grid: {
        containLabel: true,
        top: 20,
        left: 40,
        right: 40,
        bottom: 10
      },
      series: [
        {
          data: data.value.map((item) => {
            return item.count;
          }),
          type: 'line',
          lineStyle: {
            color: '#1795FF',
            width: 2
          },
          areaStyle: {
            color: {
              type: 'linear',
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [
                {
                  offset: 0.1,
                  color: 'rgba(64, 175, 239, 0.2)' // 0% 处的颜色
                },
                {
                  offset: 1,
                  color: 'rgba(64, 175, 239, 0)' // 100% 处的颜色
                }
              ]
            }
          }
        }
      ]
    };
  });
</script>
如果你不想使用 `defineComponent` 来定义组件,也可以使用 Vue3 的 `defineAsyncComponent` 函数异步加载组件,并在组件的 `setup` 函数中使用 `ref` 创建响应式数据。 以下是示例代码: ```typescript <template> <div> <my-echarts :options="options" :auto-resize="true" :renderer="'canvas'" :chart="chartRef"></my-echarts> </div> </template> <script lang="ts"> import { defineAsyncComponent, onMounted, ref } from 'vue' import * as echarts from 'echarts' import { use } from 'echarts/core' import { CanvasRenderer } from 'echarts/renderers' import { PieChart } from 'echarts/charts' import { LegendComponent, TooltipComponent } from 'echarts/components' import VueECharts from 'vue-echarts' use([CanvasRenderer, PieChart, LegendComponent, TooltipComponent]) const MyECharts = defineAsyncComponent(() => import('vue-echarts')) export default { components: { MyECharts }, setup() { const chartRef = ref(null) const chart = ref<echarts.ECharts | null>(null) const options: echarts.EChartsOption = { title: { text: '环形图示例' }, tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' }, legend: { orient: 'vertical', left: 10, data: ['数据1', '数据2', '数据3', '数据4', '数据5'] }, series: [ { name: '访问来源', type: 'pie', radius: ['50%', '70%'], avoidLabelOverlap: false, label: { show: false, position: 'center' }, emphasis: { label: { show: true, fontSize: '30', fontWeight: 'bold' } }, labelLine: { show: false }, data: [ { value: 335, name: '数据1' }, { value: 310, name: '数据2' }, { value: 234, name: '数据3' }, { value: 135, name: '数据4' }, { value: 1548, name: '数据5' } ] } ] } onMounted(() => { if (chartRef.value) { chart.value = echarts.init(chartRef.value) chart.value.setOption(options) } }) return { chartRef, options } } } </script> ``` 注意,在这个示例中,我们使用了 `defineAsyncComponent` 函数异步加载 `vue-echarts` 组件,并使用 `ref` 函数创建了 `chartRef` 响应式数据。在 `setup` 函数中使用 `onMounted` 钩子函数初始化 Echarts 实例并设置选项,并返回 `chartRef` 和 `options` 数据。在模板中,我们通过 `<my-echarts>` 标签来使用异步加载的 `vue-echarts` 组件,将 `chartRef` 和 `options` 作为属性传入。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值