工作中做了几个大屏可视化项目,必用Echarts,通常一个页面中会有多个Echarts图表,避免重复渲染,代码冗余将Echarts的基础配置封装成了一个共用组件
共用组件:
<template>
<div ref="chartRef" :style="{ height }" />
</template>
<script>
import { defineComponent, getCurrentInstance, onMounted, onBeforeMount, onBeforeUnmount, nextTick, watchEffect} from "vue";
//引入echarts
import * as echarts from "echarts";
//如果需要中国地图
import china from '@/assets/js/china.json';
echarts.registerMap('china', china);
//如果需要tooltip自动轮播
import tools from '@/utils/tooltip-auto-show-vue';
let chartsArr = [];
export default defineComponent({
name: "BaseEcharts",
props: {
height: {
type: String,
default: "300px",
},
options: {
type: Object,
default: () => ({})
},
},
setup(props) {
//setup执行时组件对象还没有创建,我们可以通过 getCurrentInstance这个函数来返回当前组件的实例对象
const { proxy } = getCurrentInstance();
const initCharts = () => {
//通过Promise异步操作,避免报错Initialize failed: invalid dom
//1:新建一个promise对象
let newPromise = new Promise((resolve) => {
resolve();
});
// 2:然后异步执行echarts的初始化函数
newPromise.then(() => {
const myChart = echarts.init(proxy.$refs.chartRef);
let tootipTimer = null;
//侦听配置改变后重新渲染,必须放在newPromise.then()中,否则会出现异步问题,每次渲染都是上一次的结果
watchEffect(()=>{
myChart.setOption(props.options);
tootipTimer && tootipTimer.clearLoop();
tootipTimer = null;
tootipTimer = tools.loopShowTooltip(myChart, props.options, {
interval: 3000, // 轮播间隔时间
loopSeries: true // 是否开启轮播循环
});
})
chartsArr.push(myChart);
});
};
//窗口resize事件
const handleChartResize = () => {
for(var i = 0;i < chartsArr.length;i++) {
chartsArr[i] && chartsArr[i].resize();
}
};
onBeforeMount(() => {
nextTick(() => {
initCharts();
});
});
onMounted(() => {
window.addEventListener("resize", handleChartResize);
});
onBeforeUnmount(() => {
window.removeEventListener('resize', handleChartResize);;
});
return {
};
}
});
</script>
<style lang="scss" scoped></style>
view中使用:
<template>
<BaseEcharts :options="options" :height="echartsHeight" style="width:100%"/>
</template>
<script setup>
import BaseEcharts from './BaseEcharts.vue'
//设置图表高度
const echartsHeight = '300px'
//图表自定义配置
const options = {
...
}
<script>