echarts在vue3中妙用

vue中使用Echarts

引入

安装完Echarts包后,我们安装官网指示,使用按需导入。

文件:/src/plugin/echarts.ts

import type { App } from "vue";

import * as echarts from "echarts/core";
import { BarChart, LineChart } from "echarts/charts";
import { CanvasRenderer, SVGRenderer } from "echarts/renderers";
import { UniversalTransition, LabelLayout } from "echarts/features";
import {
  GridComponent,
  TitleComponent,
  DatasetComponent,
  TransformComponent,
  TooltipComponent,
} from "echarts/components";

import type {
  // 系列类型的定义后缀都为 SeriesOption
  BarSeriesOption,
  LineSeriesOption,
} from "echarts/charts";
import type {
  // 组件类型的定义后缀都为 ComponentOption
  TitleComponentOption,
  TooltipComponentOption,
  GridComponentOption,
  DatasetComponentOption,
} from "echarts/components";
import type { ComposeOption } from "echarts/core";

// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
export type ECOption = ComposeOption<
  | BarSeriesOption
  | LineSeriesOption
  | TitleComponentOption
  | TooltipComponentOption
  | GridComponentOption
  | DatasetComponentOption
>;

// 注册组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  BarChart,
  LineChart,
  LabelLayout,
  UniversalTransition,
  CanvasRenderer,
  SVGRenderer,
]);

export function initEcharts(app: App) {
  console.log("初始化echarts");
  app.config.globalProperties.$echarts = echarts;
}
export default echarts;

编写基础Echarts组件

我们想要实现一个只需传入option的就可以重复复用的组件。

<template>
  <div class="chart" style="width: 100%; height: 100%" ref="chartRef"></div>
</template>

<script setup lang="ts">
import { onMounted, ref, shallowRef, watch } from "vue";
import useEcharts, { type TEchartsOptions } from "../hook/useEchart";
import { useThemeHooks } from "../store/moudle/theme";

const props = defineProps<{
  option: TEchartsOptions;
}>();
const themeColor = useThemeHooks();
const chartRef = ref<HTMLDivElement>();
const currentOption = shallowRef(props.option);

const { setOptions, initEcharts } = useEcharts(
  chartRef,
  currentOption.value,
  true
);
// 监听options的变化。如果变化就重新设置options
watch(
  () => props.option,
  (newVal) => {
    let targetOPtion: TEchartsOptions = {};
    if (themeColor.theme && themeColor.theme.length > 0) {
      targetOPtion = { ...newVal, color: themeColor.theme };
    } else {
      targetOPtion = { ...newVal };
    }
    setOptions(targetOPtion);
  }
);
//监听主题变化。
watch(
  () => themeColor.theme,
  (newVal) => {
    if (newVal && newVal.length > 0) {
      setOptions({ color: newVal });
    }
  }
);
onMounted(() => {
  initEcharts();
});
</script>

Hooks设计

import {
  onDeactivated,
  onMounted,
  onUnmounted,
  shallowRef,
  type Ref,
} from "vue";

import echarts from "../plugins/echarts";

export type TEchartsOptions = echarts.EChartsCoreOption;

export default function useEcharts(
  elRef: Ref<HTMLElement | undefined>,
  option: TEchartsOptions,
  isResize = false
) {
  const myEcharts = shallowRef<echarts.ECharts>();
  const initEcharts = (theme: string[] | null = null) => {
    myEcharts.value = echarts.init(elRef.value, theme);
    setOptions(option);
  };

  const setOptions = (options: TEchartsOptions) => {
    options && myEcharts.value?.setOption(options);
  };
  const reSize = () => {
    myEcharts.value?.resize();
  };

  onMounted(() => {
    if (isResize) {
      window.addEventListener("resize", reSize);
    }
  });

  //如果页面keepLived,则需要移除resize事件
  onDeactivated(() => {
    window.removeEventListener("resize", reSize);
  });

  onUnmounted(() => {
    myEcharts.value?.dispose();
  });

  return {
    initEcharts,
    setOptions,
    reSize,
  };
}

全局主题颜色变量

这里使用pinia库来实现全局变量

import { defineStore } from "pinia";
import { store } from "..";
import theme from "echarts/types/src/theme/dark.js";

const useThemeStore = defineStore("theme", {
  state: () => {
    return {
      themeName: "vintage",
      theme: [
        "#d87c7c",
        "#919e8b",
        "#d7ab82",
        "#6e7074",
        "#61a0a8",
        "#efa18d",
        "#787464",
        "#cc7e63",
        "#724e58",
        "#4b565b",
      ],
    };
  },
  actions: {
    changeTheme(theme: string[], name: string) {
      this.theme = theme;
      this.themeName = name;
    },
  },
});

export function useThemeHooks() {
  return useThemeStore(store);
}

这里提供一些主要颜色

export const echartsThemeData = [
  {
    name: "vintage",
    background: "#fef8ef",
    theme: [
      "#d87c7c",
      "#919e8b",
      "#d7ab82",
      "#6e7074",
      "#61a0a8",
      "#efa18d",
      "#787464",
      "#cc7e63",
      "#724e58",
      "#4b565b",
    ],
  },
  {
    name: "dark",
    background: "#333",
    theme: [
      "#dd6b66",
      "#759aa0",
      "#e69d87",
      "#8dc1a9",
      "#ea7e53",
      "#eedd78",
      "#73a373",
      "#73b9bc",
      "#7289ab",
      "#91ca8c",
      "#f49f42",
    ],
  },
  {
    name: "westeros",
    background: "transparent",
    theme: ["#516b91", "#59c4e6", "#edafda", "#93b7e3", "#a5e7f0", "#cbb0e3"],
  },
  {
    name: "essos",
    background: "rgba(242,234,191,0.15)",
    theme: ["#893448", "#d95850", "#eb8146", "#ffb248", "#f2d643", "#ebdba4"],
  },
  {
    name: "wonderland",
    background: "transparent",
    theme: ["#4ea397", "#22c3aa", "#7bd9a5", "#d0648a", "#f58db2", "#f2b3c9"],
  },
  {
    name: "walden",
    background: "rgba(252,252,252,0)",
    theme: ["#3fb1e3", "#6be6c1", "#626c91", "#a0a7e6", "#c4ebad", "#96dee8"],
  },
  {
    name: "chalk",
    background: "#293441",
    theme: [
      "#fc97af",
      "#87f7cf",
      "#f7f494",
      "#72ccff",
      "#f7c5a0",
      "#d4a4eb",
      "#d2f5a6",
      "#76f2f2",
    ],
  },
  {
    name: "infographic",
    background: "transparent",
    theme: [
      "#C1232B",
      "#27727B",
      "#FCCE10",
      "#E87C25",
      "#B5C334",
      "#FE8463",
      "#9BCA63",
      "#FAD860",
      "#F3A43B",
      "#60C0DD",
      "#D7504B",
      "#C6E579",
      "#F4E001",
      "#F0805A",
      "#26C0C0",
    ],
  },
  {
    name: "macarons",
    background: "transparent",
    theme: [
      "#2ec7c9",
      "#b6a2de",
      "#5ab1ef",
      "#ffb980",
      "#d87a80",
      "#8d98b3",
      "#e5cf0d",
      "#97b552",
      "#95706d",
      "#dc69aa",
      "#07a2a4",
      "#9a7fd1",
      "#588dd5",
      "#f5994e",
      "#c05050",
      "#59678c",
      "#c9ab00",
      "#7eb00a",
      "#6f5553",
      "#c14089",
    ],
  },
  {
    name: "roma",
    background: "transparent",
    theme: [
      "#E01F54",
      "#001852",
      "#f5e8c8",
      "#b8d2c7",
      "#c6b38e",
      "#a4d8c2",
      "#f3d999",
      "#d3758f",
      "#dcc392",
      "#2e4783",
      "#82b6e9",
      "#ff6347",
      "#a092f1",
      "#0a915d",
      "#eaf889",
      "#6699FF",
      "#ff6666",
      "#3cb371",
      "#d5b158",
      "#38b6b6",
    ],
  },
  {
    name: "shine",
    background: "transparent",
    theme: [
      "#c12e34",
      "#e6b600",
      "#0098d9",
      "#2b821d",
      "#005eaa",
      "#339ca8",
      "#cda819",
      "#32a487",
    ],
  },
  {
    name: "purple-passion",
    background: "rgba(91,92,110,1)",
    theme: ["#8a7ca8", "#e098c7", "#8fd3e8", "#71669e", "#cc70af", "#7cb4cc"],
  },
];

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值