共计 2195 个字符,预计需要花费 6 分钟才能阅读完成。
话不多说,间接上代码吧
新增一个 MyCharts.vue 文件, 文件内容如下
<!--
/**
* Author: 前端小高
* Desc: MyCharts 图表组件
*/
-->
<template>
<div :id="chartId" :style="getChartStyle"></div>
</template>
<script name="MyCharts" lang="ts" setup>
import {
ref,
shallowRef,
computed,
watch,
onMounted,
onBeforeUnmount,
getCurrentInstance,
PropType
} from 'vue'
import {debounce} from 'lodash'
const {proxy} = getCurrentInstance() as any
const props = defineProps({
options: {
type: Object,
default: () => {return {}
}
},
height: {
type: Number,
default: 300
},
// 是否不跟之前的传入值合并
notMerge: {
type: Boolean,
default: true
}
})
const getChartStyle = computed(() => {
return {
width: '100%',
height: `${props.height}px`
}
})
watch(() => props.options,
() => {initChart()
},
{deep: true}
)
// 默认显示的图表配置数据
const defaultOptions = {
tooltip: {trigger: 'axis'},
legend: {data: ['Email', 'Union Ads']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {type: 'value'},
series: [
{
name: 'Email',
type: 'line',
smooth: true,
stack: 'Total',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: 'Union Ads',
type: 'line',
smooth: true,
stack: 'Total',
data: [220, 182, 191, 234, 290, 330, 310]
}
]
}
const getRandomStr = () => {const randomNumStr = String(Math.random()).split('.')[1]
return randomNumStr
}
const chartId = ref('chart-id')
const getChartId = () => {const str = 'chart-id-' + getRandomStr()
chartId.value = str
}
getChartId()
const resizeHandler = () => {eChartsRef.value.resize()
}
const resizeHandlerOrigin = debounce(resizeHandler, 500)
const eCharts = proxy.$ECharts
const eChartsRef = shallowRef<any>()
const initChart = () => {eChartsRef.value = eCharts.init(document.getElementById(chartId.value))
let options = {}
if (isEmptyObj(props.options)) {options = defaultOptions} else {options = props.options}
eChartsRef.value.setOption(options, props.notMerge)
window.addEventListener('resize', resizeHandlerOrigin)
}
const isEmptyObj = (obj) => {return typeof obj === 'object' && JSON.stringify(obj) === '{}'}
onMounted(() => {initChart()
})
onBeforeUnmount(() => {window.removeEventListener('resize', resizeHandlerOrigin)
eChartsRef.value.dispose()})
watch(() => props.options,
() => {initChart()
},
{deep: true}
)
</script>
<style lang="scss" scoped></style>
页面下援用组件及应用办法
<template>
<my-charts></my-charts>
</template>
<script name="TestPage" lang="ts" setup>
import MyCharts from './MyCharts.vue'
</script>
预览成果如下
正文完