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 --savelodash-es安装 npm install lodash-es --save
lodash-es 说明
介绍一下 throttle 和 debounce ,它们都可以用于 函数节流 从而提升性能,但它们还是存在一些不同的:
debounce:将短时间内多次触发的事件合并成一次事件响应函数执行(往往是在第一次事件或者在最后一次事件触发时执行),即该段时间内仅一次真正执行事件响应函数。
throttle:假如在短时间内同一事件多次触发,那么每隔一段更小的时间间隔就会执行事件响应函数,即该段时间内可能多次执行事件响应函数。