首页 > 其他分享 >vue3+vite,封装 echarts 组件以及如何使用

vue3+vite,封装 echarts 组件以及如何使用

时间:2024-03-01 16:34:17浏览次数:31  
标签:false color vue3 value props chartInstance echarts vite

1.封装 echarts 组件

1.安装 echarts 所需 npm 包,如下。
npm i [email protected]
npm i [email protected] //社区图等
npm i @vueuse/[email protected] //一些好用的hook

2.封装 echarts 组件

1.在 component 目录下新建 Echarts 文件夹
2.在Echarts 文件夹下新建 config 文件夹(按需引入 echarts)
3.config 文件夹新建 index.ts 文件,配置如下
import * as echarts from 'echarts/core';
import { BarChart, LineChart, LinesChart, PieChart, ScatterChart, RadarChart, GaugeChart } from 'echarts/charts';
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  LegendComponent,
  PolarComponent,
  GeoComponent,
  ToolboxComponent,
  DataZoomComponent,
} from 'echarts/components';
import { LabelLayout, UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
import 'echarts-liquidfill';

echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  LegendComponent,
  PolarComponent,
  GeoComponent,
  ToolboxComponent,
  DataZoomComponent,
  BarChart,
  LineChart,
  LinesChart,
  PieChart,
  ScatterChart,
  RadarChart,
  GaugeChart,
  LabelLayout,
  UniversalTransition,
  CanvasRenderer,
]);

export default echarts;
4.在 Echarts 目录下,新建 index.vue 文件,封装如下
<template>
  <div id="echarts" ref="chartRef" :style="echartsStyle" />
</template>

<script setup lang="ts" name="ECharts">
import { ref, onMounted, onBeforeUnmount, watch, computed, markRaw, nextTick } from "vue";
import echarts from "./config";
import { useDebounceFn } from "@vueuse/core";

interface Props {
  option: any;
  renderer?: "canvas" | "svg";
  resize?: boolean;
  theme?: Object | string;
  width?: number | string;
  height?: number | string;
  onClick?: (event: any) => any;
}

const props = withDefaults(defineProps<Props>(), {
  renderer: "canvas",
  resize: true
});

const echartsStyle = computed(() => {
  return props.width || props.height
	? { height: props.height + "px", width: props.width + "px" }
	: { height: "100%", width: "100%" };
});

const chartRef = ref<HTMLDivElement | HTMLCanvasElement>();
const chartInstance = ref();

const draw = () => {
  if (chartInstance.value) {
	chartInstance.value.setOption(props.option, { notMerge: true });
  }
};

watch(props, () => {
  draw();
});

const handleClick = (event: any) => props.onClick && props.onClick(event);

const init = () => {
  if (!chartRef.value) return;
  chartInstance.value = echarts.getInstanceByDom(chartRef.value);

  if (!chartInstance.value) {
	chartInstance.value = markRaw(
	  echarts.init(chartRef.value, props.theme, {
		renderer: props.renderer
	  })
	);
	chartInstance.value.on("click", handleClick);
	draw();
  }
};

const resize = () => {
  if (chartInstance.value && props.resize) {
	chartInstance.value.resize({ animation: { duration: 300 } });
  }
};

const debouncedResize = useDebounceFn(resize, 300, { maxWait: 800 });

onMounted(() => {
  nextTick(() => init());
  window.addEventListener("resize", debouncedResize);
});

onBeforeUnmount(() => {
  chartInstance.value?.dispose();
  window.removeEventListener("resize", debouncedResize);
});

defineExpose({
  getInstance: () => chartInstance.value,
  resize,
  draw
});
</script>

3.如何使用(任何新建 index.vue)

<template>
  <div class="echarts">
	<ECharts :option="option" :resize="false" />
  </div>
</template>

<script setup lang="ts">
import ECharts from '@/components/ECharts/index.vue';

const option = {
  title: [
	{
	  text: (0.5 * 100).toFixed(0) + '%',
	  left: '49%',
	  top: '35%',
	  textAlign: 'center',
	  textStyle: {
		fontSize: '16',
		fontWeight: 'normal',
		color: '#ffffff',
		align: 'center',
		textBorderColor: 'rgba(0, 0, 0, 0)',
		textShadowColor: '#000',
		textShadowBlur: 0,
		textShadowOffsetX: 0,
		textShadowOffsetY: 1,
	  },
	},
	{
	  text: '预约量',
	  left: '49%',
	  top: '25%',
	  textAlign: 'center',
	  textStyle: {
		fontSize: '15',
		fontWeight: 'normal',
		color: '#ffffff',
		align: 'center',
		textBorderColor: 'rgba(0, 0, 0, 0)',
		textShadowColor: '#000',
		textShadowBlur: 0,
		textShadowOffsetX: 0,
		textShadowOffsetY: 1,
	  },
	},
  ],
  grid: {
	top: '0',
	left: '0px',
	right: '0px',
	bottom: '0',
	containLabel: true,
  },
  polar: {
	radius: ['75%', '85%'],
	center: ['50%', '50%'],
  },
  angleAxis: {
	max: 120,
	clockwise: false,
	axisLine: {
	  show: false,
	},
	axisTick: {
	  show: false,
	},
	axisLabel: {
	  show: false,
	},
	splitLine: {
	  show: false,
	},
	startAngle: 188,
  },
  radiusAxis: {
	type: 'category',
	show: true,
	axisLabel: {
	  show: false,
	},
	axisLine: {
	  show: false,
	},
	axisTick: {
	  show: false,
	},
  },
  series: [
	{
	  type: 'liquidFill',
	  radius: '70%',
	  z: 2,
	  center: ['50%', '50%'],
	  data: [0.4, 0.4, 0.4],
	  itemStyle: {
		color: {
		  type: 'linear',
		  x: 0,
		  y: 0,
		  x2: 0,
		  y2: 1,
		  colorStops: [
			{ offset: 0, color: '#35FAB6' },
			{ offset: 1, color: 'rgba(40, 209, 247,0.3)' },
		  ],
		  global: false,
		},
	  },
	  outline: {
		borderDistance: 0,
		itemStyle: {
		  borderWidth: 2,
		  borderColor: '#31d8d5',
		  shadowBlur: 20,
		  shadowColor: '#50c1a7',
		},
	  },
	  label: {
		show: false,
	  },
	  backgroundStyle: {
		borderWidth: 1,
		color: {
		  type: 'radial',
		  x: 0.5,
		  y: 0.5,
		  r: 0.5,
		  colorStops: [
			{ offset: 0, color: '#0D2648' },
			{ offset: 0.8, color: '#0D2648' },
			{ offset: 1, color: '#228E7D' },
		  ],
		  global: false,
		},
	  },
	},
	{
	  type: 'pie',
	  radius: ['80%', '80%'],
	  center: ['50%', '50%'],
	  z: 1,
	  label: { show: false },
	  silent: true,
	  itemStyle: {
		borderWidth: 2,
		borderType: [8, 10],
		borderDashOffset: 15,
		borderColor: '#31d8d5',
		color: '#11144e',
		borderCap: 'round',
	  },
	  data: [100],
	},
	{
	  type: 'bar',
	  data: [55],
	  z: 10,
	  coordinateSystem: 'polar',
	  roundCap: true,
	  color: '#31d8d5',
	},
  ],
};
</script>

<style lang="less" scoped>
.echarts {
  width: 100%;
  height: calc(100% - 50px);
}
</style>

标签:false,color,vue3,value,props,chartInstance,echarts,vite
From: https://www.cnblogs.com/songkomei/p/18047394

相关文章

  • Vue3通过provide/inject设置全局变量
    在Vue3中,你可以使用组合API来注入和使用全局变量。组合API提供了一种更灵活的方式来组织和重用组件逻辑,包括全局状态的管理。以下是在Vue3中使用组合API来注入和使用全局变量的基本步骤:创建全局变量:在一个单独的文件中,创建全局变量并导出它,使其可在整个应用中使用......
  • Vue3组件库搭建及测试
    一、搭建Vite环境1.创建目录&初始化包配置&安装Vite依赖mkdirgresgying-uicdgresgying-uinpminitnpmivite-D2.根目录创建index.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Gresgyi......
  • vue3——环境变量的配置
    vue3环境变量的配置开发环境(development)测试环境(testing)生产环境(production)项目根目录分别添加开发、生产和测试环境的文件!.env.development.env.production.env.test文件内容变量必须以VITE_为前缀才能暴露给外部读取NODE_ENV='development'VITE_APP_TITLE=......
  • vue3笔记 computed计算属性
    计算属性有缓存的,方法没有缓存下列的计算案例是只读的,不可修改的 上述代码为只读属性,优化后<scriptsetuplang="ts">import{ref,computed}from'vue'letname=ref("zhang")letxing=ref("sang")console.log(name.value)letfullName=compute......
  • vue3 echart组件封装
    项目中用到了很多echart图表,进行了简单的组件封装,主要包含以下功能:创建图表实例,渲染图表支持传入自定义函数,可拿到图表实例,实现个性化功能支持配置更新后图表自动刷新,可配置是清空后再刷新loading状态控制resize时图表更新支持饼图默认高亮功能实现资源引入echart资源......
  • 基于Vue(提供Vue2/Vue3版本)和.Net Core前后端分离、强大、跨平台的快速开发框架
    前言今天大姚给大家推荐一款基于Vue(提供Vue2/Vue3版本)和.NetCore前后端分离、开源免费(MITLicense)、强大、跨平台的快速开发框架,并且框架内置代码生成器(解决重复性工作,提高开发效率),支持移动端(iOS/Android/H5/微信小程序):Vue.NetCore。提高开发生产效率、避免996可以考虑试试这......
  • Vue3 配合 Element-Plus 和 iframe-resizer 完美实现抽屉 Drawer 和 iframe
    环境准备pnpminstallvuelodashelement-plusiframe-resizerpnpminstall@types/iframe-resizer-Diframe新建文件src/utils/directives/iframeResize.ts​import{Directive,DirectiveBinding,nextTick}from"vue"importiframeResizefrom"iframe-r......
  • Vue3学习(二十)- 富文本插件wangeditor的使用
    写在前面学习、写作、工作、生活,都跟心情有很大关系,甚至有时候我更喜欢一个人独处,戴上耳机coding的感觉。明显现在的心情,比中午和上午好多了,心情超棒的,靠自己解决了两个问题:新增的时候点击TreeSelect控件控制台会给出报错分类新增和编辑时,报错父类和电子书iD不能为空的问题......
  • vue3router
    4.路由4.1.【对路由的理解】4.2.【基本切换效果】Vue3中要使用vue-router的最新版本,目前是4版本。路由配置文件代码如下:import{createRouter,createWebHistory}from'vue-router'importHomefrom'@/pages/Home.vue'importNewsfrom'@/pages/News.vue'importAb......
  • vue3笔记
    2.3.【一个简单的效果】Vue3向下兼容Vue2语法,且Vue3中的模板中可以没有根标签<template> <divclass="person">  <h2>姓名:{{name}}</h2>  <h2>年龄:{{age}}</h2>  <button@click="changeName">修改名字</button>  <button......