记录 vue3+Ts 项目中,按需引入echarts并进行二次封装使用。
1、安装:npm i echarts
2、新增按需引入配置文件:echartsConfig.ts
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
import * as echarts from "echarts/core";// 引入内置组件,组件后缀都为Component
import {TitleComponent,TooltipComponent,GridComponent,PolarComponent,AriaComponent,ParallelComponent,LegendComponent,RadarComponent,ToolboxComponent,DatasetComponent, // 数据集组件DataZoomComponent,VisualMapComponent,TimelineComponent,CalendarComponent,GraphicComponent,TransformComponent, // 数据转换器组件(filter, sort)
} from "echarts/components";// 引入渲染器:echarst默认使用canvas渲染,引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer, SVGRenderer } from "echarts/renderers";// 标签自动布局、全局过渡动画等特性
import { LabelLayout, UniversalTransition } from "echarts/features";// 引入图表类型,后缀都为Chart
import {BarChart,LineChart,PieChart,MapChart,RadarChart,PictorialBarChart,
} from "echarts/charts";// 注册必须的组件
echarts.use([// 内置组件TitleComponent,TooltipComponent,GridComponent,PolarComponent,AriaComponent,ParallelComponent,LegendComponent,RadarComponent,ToolboxComponent,DatasetComponent,DataZoomComponent,VisualMapComponent,TimelineComponent,CalendarComponent,GraphicComponent,TransformComponent,// 渲染器CanvasRenderer,SVGRenderer,// 特性LabelLayout,UniversalTransition,// 图表BarChart,LineChart,PieChart,MapChart,RadarChart,PictorialBarChart,
]);export default echarts;
3、封装成hooks:useEcharts.ts
import {Ref,shallowRef,unref,onMounted,onDeactivated,onBeforeUnmount,
} from "vue";import echarts from "@/components/baseEcharts/config";export type EChartsCoreOption = echarts.EChartsCoreOption;const useEcharts = (elRef: Ref<HTMLDivElement>, options: EChartsCoreOption) => {const charts = shallowRef<echarts.ECharts>();const setOptions = (options: EChartsCoreOption) => {charts.value && charts.value.setOption(options);};// 初始化const initCharts = (themeColor?: Array<string>) => {const el = unref(elRef);if (!el || !unref(el)) {return;}charts.value = echarts.init(el);if (themeColor) {options.color = themeColor;}setOptions(options);};// 重新窗口变化时,重新计算const resize = () => {charts.value && charts.value.resize();};onMounted(() => {window.addEventListener("resize", resize);});// 页面keepAlive时,不监听页面onDeactivated(() => {window.removeEventListener("resize", resize);});onBeforeUnmount(() => {window.removeEventListener("resize", resize);});return {initCharts,setOptions,resize,};
};export { useEcharts };
4、封装成基础组件:baseEcharts.vue
<template><div:style="{width: width,height: height,}"ref="echartsRef"/>
</template><script setup lang="ts">
import { ref, onMounted, watch, PropType } from "vue";
import { useEcharts, EChartsCoreOption } from "./useEchart.ts"; // 引入hooksconst props = defineProps({options: { type: Object as PropType<EChartsCoreOption>, required: true },height: { type: String, default: "100%" },width: { type: String, default: "100%" },themeColors: { type: Array as PropType<string[]>, default: () => [] },
});const echartsRef = ref();const { setOptions, initCharts } = useEcharts(echartsRef, props.options);watch(() => props.options,(nVal) => {let targetOptions: EChartsCoreOption = {};if (props.themeColors && props.themeColors.length > 0) {targetOptions = { ...nVal };targetOptions.color = props.themeColors;} else {targetOptions = { ...nVal };}setOptions(targetOptions);}
);onMounted(() => {initCharts();
});
</script>
5、使用示例:useExample.vue
<template><BaseEcharts :options="options" height="300px" />
</template><script lang="ts" setup>
import BaseEcharts from "@/components/baseEcharts/index.vue";const options = {title: {text: "使用示例",subtext: "二级标题",subTextStyle: {fontSize: 16,fontWeight: "normal",left: "center",y: "center",},},tooltip: {trigger: "axis",axisPointer: {lineStyle: {width: 1,color: "#008000",},},},grid: {left: "1%",right: "1%",bottom: "1%",top: "60px",containLabel: true,},xAxis: {type: "category",data: ["1月", "2月", "3月", "4月", "5月", "6月", "7月"],axisLabel: {interval: 0,rotate: 30,},},yAxis: {axisLabel: {formatter: (val: number) => {return val;},},},series: [{name: "收入",type: "bar",stack: "Total",data: [200, 301, 402, 503, 604, 705, 806],},{name: "支出",type: "line",stack: "Total",data: [100, 210, 1020, 230, 20, 250, 60],},],
};
</script>