Vue3 echarts自适应解决方案
resize.ts
import { nextTick, ref } from 'vue'
import { debounce } from 'lodash-es'
import elementResizeDetectorMaker from 'element-resize-detector'
export default function () {
/*chart 是echarts图的实例*/
const chart = ref()
/*检测需要监听的元素是否缩放*/
let sidebarElm: Element
/*使用element-resize-detector 来监听需要监听的元素是否产生变化*/
const erd = elementResizeDetectorMaker()
const chartResizeHandler = debounce(
() => {
if (chart.value) {
chart.value.resize()
}
},
100,
{ trailing: true }
)
/*移除窗口大小变化监听*/
const sidebarResizeHandler = () => {
nextTick(() => {
chartResizeHandler()
})
}
/*添加窗口大小变化监听*/
const initResizeEvent = () => {
window.addEventListener('resize', chartResizeHandler)
}
/*移除窗口大小变化监听*/
const destroyResizeEvent = () => {
window.removeEventListener('resize', chartResizeHandler)
}
/*初始化 sider监听*/
const initSidebarResizeEvent = () => {
/*获取需要监听的元素的document*/
sidebarElm = document.getElementsByClassName('wisdom-layout-content')[0]
if (sidebarElm) {
erd.listenTo(sidebarElm, sidebarResizeHandler)
}
}
/*移除 sider监听*/
const destroySidebarResizeEvent = () => {
if (sidebarElm) {
erd.removeListener(sidebarElm)
}
}
const mounted = () => {
initResizeEvent()
initSidebarResizeEvent()
}
const beforeDestroy = () => {
destroyResizeEvent()
destroySidebarResizeEvent()
}
return {
chart,
mounted,
beforeDestroy,
}
}
实际使用:
<template>
<div class="chartBox">
<div :id="id" :style="{ width: '100%', height: '400px' }"></div>
</div>
</template>
<script lang="ts" setup>
import type { ComputedRef } from 'vue'
import { onMounted, nextTick, watch, computed, onBeforeUnmount } from 'vue'
import * as echarts from 'echarts'
import { LineEcharts, defaultOption } from './LineEcharts.mode'
import resize from './resize'
const { chart, mounted, beforeDestroy } = resize()
interface PropsType {
id: string
titleText: string
optionData: any
width?: number | null
}
const props = withDefaults(defineProps<PropsType>(), {
id: 'chartLineDom',
titleText: '',
optionData: () => {},
width: null,
})
const option: LineEcharts = defaultOption
const initLineChart = () => {
const el = document.getElementById(props.id)
const lineChart = echarts.init(el)
lineChart.clear()
lineChart.setOption(option, true)
chart.value = lineChart
}
onMounted(() => {
mounted()
nextTick(() => {
initLineChart()
})
})
onBeforeUnmount(() => {
beforeDestroy()
})
// 初始化 echarts
const echartsInit = () => {
option.title.text = props.titleText
option.xAxis.data = props.optionData.xAxis.data
option.legend.data = props.optionData?.legend?.data || []
option.series = []
props.optionData.series.map(item => {
option.series.push({
type: 'line',
emphasis: {
focus: 'series',
},
smooth: true,
lineStyle: {
width: 2,
},
...item,
})
})
initLineChart()
}
watch(
() => props.optionData.value,
() => {
echartsInit()
},
{ deep: true }
)
</script>
<style scoped lang="less">
.chartBox {
position: relative;
width: 100%;
}
</style>
导入包
- element-resize-detector
- 安装 npm install element-resize-detector --save
- lodash-es
- 安装 npm install lodash-es --save
lodash-es 说明
介绍一下 throttle 和 debounce ,它们都可以用于 函数节流 从而提升性能,但它们还是存在一些不同的:
debounce:将短时间内多次触发的事件合并成一次事件响应函数执行(往往是在第一次事件或者在最后一次事件触发时执行),即该段时间内仅一次真正执行事件响应函数。
throttle:假如在短时间内同一事件多次触发,那么每隔一段更小的时间间隔就会执行事件响应函数,即该段时间内可能多次执行事件响应函数。
本文暂时没有评论,来添加一个吧(●'◡'●)