1、@vueuse/core 工具库
官网地址:https://vueuse.org/guide/#installation
概念:它是为Vue 2和3服务的一套Vue Composition API的常用工具集,是目前世界上Star最高的同类型库之一。它的初衷就是将一切原本并不支持响应式的JS API变得支持响应式,省去程序员自己写相关代码引用
2、引入lodash工具库
项目为ts,引用lodash-es 版本,以及ts版本
//lodash-unified为ts版
npm i lodash-es lodash-unified -S
npm i @types/lodash-es -D
//使用判断两个对象是否相等
import { isEqual } from 'lodash-unified';
3、按需引入echarts5以及封装
参考地址:https://echarts.apache.org/handbook/zh/get-started/
第一步:npm install echarts --save
第二步创建按需引入文件echarts/index.ts
import * as echarts from 'echarts/core';
//具体组件地址:\node_modules\echarts\lib\export\charts.js
import { PieChart, BarChart, LineChart } from 'echarts/charts';
import { SVGRenderer } from 'echarts/renderers';
//具体组件地址:\node_modules\echarts\lib\export\components.js
import {
GridComponent,
TitleComponent,
LegendComponent,
ToolboxComponent,
TooltipComponent,
DataZoomComponent,
VisualMapComponent
} from 'echarts/components';
const { use, registerTheme } = echarts;
use([
PieChart,
BarChart,
LineChart,
SVGRenderer,
GridComponent,
TitleComponent,
LegendComponent,
ToolboxComponent,
TooltipComponent,
DataZoomComponent,
VisualMapComponent
]);
// 自定义主题(可以修改theme.json添加一些默认的样式)
// 配置的格式可以参考这个下载下来的格式:https://echarts.apache.org/zh/theme-builder.html
import theme from './theme.json';
registerTheme('ovilia-green', theme);
export default echarts;
第三步:封装单个组件,比如bar柱状图
<template>
<div ref="barRef" style="width: 100%; height: 100%"></div>
</template>
<script setup lang="ts">
// echarts ts 定义
import { EChartOption, ECharts } from 'echarts';
// 引入公共的echarts组件(按需实现)
import echarts from '@/plugin/echarts/index';
import { onBeforeMount, onMounted, nextTick, ref, watch } from 'vue';
import { useEventListener, tryOnUnmounted, useTimeoutFn } from '@vueuse/core';
import { isEqual } from 'lodash-unified';
//echarts实例
let echartInstance: ECharts | null;
interface optionProps {
xdata: string[];
seriesData: number[];
}
const props = withDefaults(
defineProps<{
option?: optionProps;
}>(),
{
option: () => {
return {
xdata: ['aa', 'bb', 'cc', 'dd'],
seriesData: [3, 204, 1079, 1079]
};
}
}
);
let barRef = ref<HTMLElement | null>(null);
const options = {
option: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
bottom: '20%',
height: '68%',
containLabel: true
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true
},
axisLabel: {
interval: 0
},
data: props.option && props.option.xdata
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: 'GitHub信息',
type: 'bar',
data: props.option && props.option.seriesData
}
]
}
};
function initEchartsInstance() {
if (echartInstance != null && echartInstance != undefined) {
echartInstance.dispose(); //解决echarts dom已经加载的报错
}
const echartsDom = barRef.value;
if (!echartsDom) return;
//@ts-ignore
echartInstance = echarts.init(echartsDom);
echartInstance?.clear(); //清除画布,重新渲染
echartInstance?.setOption(options.option as EChartOption);
}
onBeforeMount(() => {
nextTick(() => {
initEchartsInstance();
});
});
onMounted(() => {
nextTick(() => {
useEventListener('resize', () => {
if (!echartInstance) return;
useTimeoutFn(() => {
echartInstance?.resize();
}, 100);
});
});
});
// 监听入参有变化就重新刷新
watch(
() => props.option,
(newProps, oldProps) => {
let flag: boolean = isEqual(newProps, oldProps);
if (!flag) {
nextTick(() => {
options.option.xAxis[0].data = newProps.xdata;
options.option.series[0].data = newProps.seriesData;
initEchartsInstance();
});
}
}
);
tryOnUnmounted(() => {
if (!echartInstance) return;
echartInstance.dispose();
echartInstance = null;
});
</script>
<style scoped></style>
第四步:组件中使用
<template>
<div class="test-bar">
<ReBar />
</div>
<div class="test-bar">
<ReBar :option="options.option" />
</div>
</template>
<script setup lang="ts">
import ReBar from '@/components/echarts/ReBar.vue';
import { ref, onUnmounted, reactive } from 'vue';
let timer = ref<any>(null);
let options = reactive({
option: {
xdata: ['哈哈', '嘿嘿', '嘻嘻', '呵呵'],
seriesData: [22, 33, 55, 88]
}
});
timer.value = setInterval(() => {
options.option = {
xdata: ['哈哈', '嘿嘿', '嘻嘻', '呵呵'],
seriesData: [123, 33, 11, 34]
};
}, 3000);
onUnmounted(() => {
if (timer.value) {
clearInterval(timer.value);
timer.value = null;
}
});
</script>
<style lang="less" scoped>
.test-bar {
width: 50%;
height: 250px;
overflow: hidden;
}
</style>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。