Vue3封装Echart

488 阅读1分钟
<template>  
<div>  
<slot name="header"></slot>  
<div :id="id" :style="chartStyle"></div>  
<slot name="footer"></slot>  
</div>  
</template>  
  
<script setup lang="ts" name="CommonChart">  
import {  
onMounted,  
markRaw,  
defineProps,  
defineEmits,  
ref,  
nextTick,  
watch,  
computed,  
onUnmounted  
} from 'vue';  
import * as echarts from 'echarts';  
const props = defineProps({  
id: {  
type: String,  
required: true,  
default: 'commonChart'  
},  
width: {  
type: String,  
default: '100%'  
},  
height: {  
type: String,  
default: '100%'  
},  
// 样式  
Styles: {  
type: String,  
default: ''  
},  
// 图表配置项  
setOption: {  
type: Object[Array],  
required: true,  
default: null  
},  
// 加载状态  
showLoading: {  
type: Boolean,  
default: false  
},  
// 加载配置项  
loadConfig: {  
type: Object,  
default: () => {  
return { text: 'loading' };  
}  
}  
});  
const emits = defineEmits(['getClickEvent']);  
// 图表实例  
const myChart = ref(null);  
// 图表样式  
const chartStyle = computed(() => {  
return `width: ${props.width};height: ${props.height};${props.Styles}`;  
});  
watch(  
() => props.setOption,  
() => {  
nextTick(() => {  
myChart.value = markRaw(echarts.init(document.getElementById(props.id)));  
if (isPlainObject(props.setOption)) {  
initCharts();  
props.showLoading ? myChart.value.hideLoading() : null;  
} else {  
props.showLoading ? myChart.value.showLoading(props.loadConfig) : null;  
}  
});  
},  
{  
deep: true,  
immediate: true  
}  
);  
onMounted(() => {  
myChart.value = markRaw(echarts.init(document.getElementById(props.id)));  
if (isPlainObject(props.setOption)) {  
initCharts();  
props.showLoading ? myChart.value.hideLoading() : null;  
} else {  
props.showLoading ? myChart.value.showLoading(props.loadConfig) : null;  
}  
window.addEventListener('resize', () => {  
myChart.value.resize();  
});  
});  
onUnmounted(() => {  
window.removeEventListener('resize', () => {  
myChart.value.resize();  
});  
});  
const initCharts = () => {  
myChart.value.on('click', event => {  
emits('getClickEvent', event);  
});  
// 若鼠标滑过区域位置在当前图表范围内 鼠标设置为小手  
myChart.value.getZr().on('mousemove', param => {  
let pointInPixel = [param.offsetX, param.offsetY];  
if (myChart.value.containPixel('grid', pointInPixel)) {  
myChart.value.getZr().setCursorStyle('pointer');  
} else {  
myChart.value.getZr().setCursorStyle('default');  
}  
});  
myChart.value.setOption(props.setOption, true);  
window.addEventListener('resize', () => {  
myChart.value.resize();  
});  
};  
const isPlainObject = val => {  
return Object.prototype.toString.call(val) === '[object Object]';  
};  
</script>  
  
<style scoped></style>