随着 Vue 更新到了 V3 版本,ECharts 更新到了 V5 版本,它们均新增加了对 TypeScript 非常友好的支持。鉴于现有的开发方式与原先 Vue V2 版本仍然具有一些区别,所以本文在此给出一个新版的开发样例。
1. 示例代码
本节以标准柱形图为例,使用 Composition API 以及 TypeScript 进行代码编写。
TestChart.vue
:
1<template>
2 <div ref="chartRef" style="width: 100%; height: 400px"></div>
3</template>
4
5<script lang="ts">
6import { defineComponent, onBeforeUnmount, onMounted, ref } from "vue";
7import * as echarts from "echarts/core";
8import { BarChart } from "echarts/charts";
9import {
10 TooltipComponent,
11 GridComponent,
12 DataZoomComponent,
13} from "echarts/components";
14import { LabelLayout } from "echarts/features";
15import { CanvasRenderer } from "echarts/renderers";
16import { useChartData } from "./useChart";
17
18export default defineComponent({
19 name: "TestChart",
20 setup() {
21 const chartRef = ref<HTMLDivElement>();
22 let chart: echarts.ECharts | null = null;
23 echarts.use([
24 BarChart,
25 TooltipComponent,
26 GridComponent,
27 DataZoomComponent,
28 LabelLayout,
29 CanvasRenderer,
30 ]);
31
32 const { initOption } = useChartData();
33
34 const resizeHandler = () => {
35 chart?.resize();
36 };
37
38 onMounted(() => {
39 chart = echarts.init(chartRef.value as HTMLDivElement);
40 chart.setOption(initOption);
41
42 window.addEventListener("resize", resizeHandler);
43 });
44
45 onBeforeUnmount(() => {
46 window.removeEventListener("resize", resizeHandler);
47 chart?.dispose();
48 });
49
50 return {
51 chartRef,
52 };
53 },
54});
55</script>
当然,也可以使用 script setup
版本的代码:
TestChart.vue
script setup:
1<template>
2 <div ref="chartRef" style="width: 100%; height: 400px"></div>
3</template>
4
5<script setup lang="ts">
6import { onBeforeUnmount, onMounted, ref } from "vue";
7import * as echarts from "echarts/core";
8import { BarChart } from "echarts/charts";
9import {
10 TooltipComponent,
11 GridComponent,
12 DataZoomComponent,
13} from "echarts/components";
14import { LabelLayout } from "echarts/features";
15import { CanvasRenderer } from "echarts/renderers";
16import { useChartData } from "./useChart";
17
18const chartRef = ref<HTMLDivElement>();
19let chart: echarts.ECharts | null = null;
20echarts.use([
21 BarChart,
22 TooltipComponent,
23 GridComponent,
24 DataZoomComponent,
25 LabelLayout,
26 CanvasRenderer,
27]);
28
29const { initOption } = useChartData();
30
31const resizeHandler = () => {
32 chart?.resize();
33};
34
35onMounted(() => {
36 chart = echarts.init(chartRef.value as HTMLDivElement);
37 chart.setOption(initOption);
38
39 window.addEventListener("resize", resizeHandler);
40});
41
42onBeforeUnmount(() => {
43 window.removeEventListener("resize", resizeHandler);
44 chart?.dispose();
45});
46</script>
useChart.ts
:
1import * as echarts from "echarts/core";
2import { BarSeriesOption } from "echarts/charts";
3import {
4 TooltipComponentOption,
5 GridComponentOption,
6 DataZoomComponentOption,
7} from "echarts/components";
8
9export type ECOption = echarts.ComposeOption<
10 | BarSeriesOption
11 | TooltipComponentOption
12 | GridComponentOption
13 | DataZoomComponentOption
14>;
15
16export function useChartData(): {
17 initOption: ECOption;
18} {
19 const initOption: ECOption = {
20 tooltip: {
21 trigger: "axis",
22 axisPointer: {
23 type: "shadow",
24 },
25 },
26 xAxis: [
27 {
28 type: "category",
29 data: ["A", "B", "C", "D", "E"],
30 axisTick: {
31 alignWithLabel: true,
32 },
33 },
34 ],
35 yAxis: [
36 {
37 type: "value",
38 },
39 ],
40 dataZoom: [
41 {
42 type: "inside",
43 orient: "horizontal",
44 },
45 {
46 type: "slider",
47 orient: "horizontal",
48 start: 0,
49 end: 100,
50 },
51 ],
52 series: [
53 {
54 type: "bar",
55 data: [123, 332, 22, 1, 23],
56 label: {
57 show: true,
58 position: "top",
59 },
60 itemStyle: {
61 color: "#27727B",
62 },
63 labelLayout: {
64 hideOverlap: true,
65 },
66 emphasis: {
67 label: {
68 show: true,
69 fontWeight: "bolder",
70 fontSize: 15,
71 },
72 itemStyle: {
73 shadowColor: "rgba(0, 0, 0, 0.7)",
74 shadowBlur: 10,
75 },
76 },
77 },
78 ],
79 };
80
81 return {
82 initOption,
83 };
84}
参考链接:
2. 关于控制台报错 `resize` should not be called during main process
一般情况下,对 ECharts 图表封装并不需要将 echarts 对象暴露到渲染上下文中。如果确实有意将 echarts 对象声明为响应式,请使用 shallowRef
而非 ref
:
1// GOOD
2const chart = shallowRef<echarts.ECharts>();
3
4// BAD
5const chart = ref<echarts.ECharts>();
如果不使用 shallowRef
,可能会导致命令行报错 `resize` should not be called during main process;事实上,任何第三方库创造的实例都应当使用 shallowRef
而非 ref
进行响应式处理。
参考链接:
版权声明:本文遵循 CC BY-SA 4.0 版权协议,转载请附上原文出处链接和本声明。
Copyright statement: This article follows the CC BY-SA 4.0 copyright agreement. For reprinting, please attach the original source link and this statement.