Vue3封装Echrats组件

Vue3封装Echrats组件@TOC

Vue3封装Echrats组件

相信很多小伙伴在开发大屏可视化的项目中经常用到图表展示的模块,那么我们总不能一次又一次的声明一个容器去创建一个Echarts示例,一次又一次的init、一次又一次的setOption,接下来我们将实现一个Echarts的图表组件的封装。

在项目中引入Echarts

通过script标签引入

   下载Echarts.js,通过官方的github或者使用CDN加速器的方式引入到自己的项目中。
 <script src="./echarts.min.js"></script> //源码引入
 <script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.3.3/echarts.common.js"></script> //bootcdn引入

通过npm安装enharts

npm install echarts --save

Echarts组件的封装

<template>
  <div ref="chartRef" :class="props.className" :style="{ height: props.height, width: props.width }" />
</template>

<script lang="ts" setup>
import {
  onActivated,
  PropType,
  onMounted,
  onBeforeUnmount,
  unref,
  ref,
  watch,
  nextTick,
  defineProps,
} from 'vue';
import type { ECharts, EChartsOption } from 'echarts';
import * as echarts from 'echarts';
const props = defineProps({
  // 自定义组件的类名
  className: {
    type: String as PropType<string>,
    default: 'chart',
  },
  // 图表容器的宽度
  width: {
    type: String as PropType<string>,
    default: '100%',
  },
  // 图表容器的高度
  height: {
    type: String as PropType<string>,
    default: '100%',
  },
  // 图表参数
  options: {
    type: Object as PropType<EChartsOption | undefined>,
    default: undefined,
  },
  // 图表是否具有点击事件
  isClick: {
    type: Boolean as PropType<boolean>,
    default:false
  }
});
const chartRef = ref<HTMLCanvasElement | null>(null);
let chart: ECharts | null = null;
watch(
  () => props.options,
  (options: EChartsOption | undefined) => {
    nextTick(() => {
      if (chart) {
        chart.setOption(options as EChartsOption, true);
      }
    });
  },
  {
    deep: true,
  }
);
const emits = defineEmits(['callbackFun'])
onMounted(() => {
  // 设置异步,不然图例一开始的宽度不正确。
  nextTick(() => {
    initChart();
  });
});
const initChart = (): void => {
  // 初始化echart
  const chartRefWrap = unref(chartRef);
  if (chartRefWrap) {
    chart = echarts.init(chartRefWrap);
    // 若图表需要点击事件做些其他功能,在初始化示例时注册图表的点击事件
    if (props.isClick) {
      chart.on('click', (params: any) => {
        emits('callbackFun',params)
      })
    }
    chart.setOption(props.options as EChartsOption, true);
    window.addEventListener('resize',chartsResize)
  }
};
onActivated(() => {
  // 防止keep-alive之后图表变形
  if (chart) {
    nextTick(() => {
      chart.resize();
    })
  }
});

const chartsResize = () => {
  chart && chart.resize();
};

onBeforeUnmount(() => {
  
  window.removeEventListener('resize',chartsResize);
  chart = nll;
});
</script>

<style>
</style>
   

Echarts组件的使用 (含点击事件)

<template>
  <div class="myEcharts">
    <Echarts
      width="100%"
      height="100%"
      :options="data.myEchartsOption"
      isClick
      @callbackFun="callbackFun"
    />
  </div>
</template>

<script lang="ts" setup>
import * as echarts from "echarts";
import Echarts from "@/components/Charts/index.vue";
import { reactive } from "vue";
const data = reactive({
  myEchartsOption: {
    backgroundColor: "#061740",
    grid: {
      x: 0,
      y: 0,
      x2: 0,
      y2: 0,
      top: "15%",
      left: "3%",
      right: "3%",
      bottom: "20%",
      containLabel: true,
    },
    legend: {
      data: ["季度销售额", "销售增长率"],
      bottom: "bottom",
      type: "scroll",
      padding: [10, 0, 0, 0],
      textStyle: {
        color: "rgba(36, 173, 254, 1)",
        fontSize: "1rem",
      },
      //图例标记的图形高度
      itemHeight: 5,
      //图例标记的图形宽度
      itemWidth: 10,
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow",
      },
    },
    xAxis: [
      {
        type: "category",
        axisTick: {
          show: false,
        },
        interval: 1,
        axisLabel: {
          color: "rgba(36, 173, 254, 1)",
          fontSize: "24",
        },
        axisLine: {
          show: false,
        },
        data: ["第一季度", "第二季度", "第三季度"],
      },
    ],
    yAxis: [
      {
        type: "value",
        splitNumber: 5,
        splitLine: {
          show: true,
          lineStyle: {
            type: "dashed",
            color: "rgba(36, 173, 254, 0.2)",
          },
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          textStyle: {
            color: "rgba(36, 173, 254, 1)",
          },
          fontSize: "24",
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: "rgba(36, 173, 254, 1)",
          },
        },
      },
      {
        type: "value",
        splitNumber: 5,
        splitLine: {
          show: true,
          lineStyle: {
            type: "dashed",
            color: "rgba(36, 173, 254, 0.2)",
          },
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          textStyle: {
            color: "rgba(36, 173, 254, 1)",
          },
          fontSize: "24",
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: "rgba(36, 173, 254, 1)",
          },
        },
      },
    ],
    series: [
      {
        name: "季度销售额",
        type: "bar",
        barWidth: "20%",
        data: ["13", "25", "38"],
        //背景色
        showBackground: true,
        backgroundStyle: {
          color: "rgba(180, 180, 180, 0.2)",
        },
        //柱体颜色
        itemStyle: {
          normal: {
            //圆角
            barBorderRadius: [30, 30, 0, 0],
            //柱图高亮渐变色
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: "#77DDFF",
              },
              {
                offset: 0.5,
                color: 
                "#00BBFF",
              },
              {
                offset: 1,
                color: "#009FCC",
              },
            ]),
          },
        },
      },
      {
        type: "line",
        stack: "Total",
        name: "销售增长率",
        emphasis: {
          focus: "series",
        },
        yAxisIndex: 1,
        data: ["40", "28", "26"],
        itemStyle: {
          normal: {
            color: "#FFBB00", //改变折线点的颜色
            lineStyle: {
              color: "#FFBB00", //改变折线颜色
              type: "dashed",
            },
          },
        },
        symbol: "circle",
        symbolSize: 15,
      },
    ],
  },
});
// echarts组件的点击抛出事件
const callbackFun = (obj) => {
  console.log(obj, "拿到对象做点你需要的功能");
};
</script>
<style scoped lang="less">
.myEcharts {
  width: 100%;
  height: 100%;
}
</style>

效果图

在这里插入图片描述

点击事件的说明

当你不需要点击事件时,你不需要传入isClick参数和接收callbackFun事件
当你需要点击图表触发其他自定义业务代码时,传入isClick参数和接收callbackFun事件

<template>
  <div class="myEcharts">
    <Echarts
      width="100%"
      height="100%"
      :options="data.myEchartsOption"
    />
  </div>
</template>

点击事件的效果打印

在这里插入图片描述

总结

一直在不断前进,如有问题,请各位看官指出,相互交流学习。

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于使用 Vue 3 和 ECharts 创建柱状图,您可以按照以下步骤进行操作: 1. 首先,确保您已经安装了 Vue 3 和 ECharts。可以使用以下命令进行安装: ```bash npm install vue@next echarts ``` 2. 在 Vue 组件中引入 ECharts 和其样式文件。可以在 `main.js` 或者需要使用柱状图的组件中进行引入: ```javascript import { createApp } from 'vue'; import * as echarts from 'echarts'; import 'echarts/dist/echarts.min.css'; const app = createApp(App); app.config.globalProperties.$echarts = echarts; app.mount('#app'); ``` 3. 在需要显示柱状图的组件中,创建一个容器来容纳图表,并引入 ECharts 的实例: ```html <template> <div class="chart-container"> <div ref="chart" style="width: 100%; height: 400px;"></div> </div> </template> <script> export default { mounted() { this.renderChart(); }, methods: { renderChart() { const chartDom = this.$refs.chart; const myChart = this.$echarts.init(chartDom); // 在这里使用 ECharts 的 API 绘制柱状图 // 例如: myChart.setOption({ title: { text: '柱状图示例' }, xAxis: { type: 'category', data: ['A', 'B', 'C', 'D', 'E'] }, yAxis: { type: 'value' }, series: [{ data: [10, 20, 30, 40, 50], type: 'bar' }] }); } } }; </script> <style scoped> .chart-container { width: 100%; height: 400px; } </style> ``` 以上是一个简单的示例,您可以根据您的需求进行进一步的配置和样式调整。希望对您有所帮助!如果您有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值