ResizeObserver 用于vue+Echarts图表 父元素百分比大小时自适应大小问题的解决方案

116 阅读1分钟

本解决方案主要使用了浏览器zeObserver API,注意为了减少长度删掉了图表的配置信息。 大致流程是保存图表id和图表到map,在回调函数中遍历父元素获取id,并根据id,调用对应图表的resize 方法。

<template>
    <div class="box" :class="id" v-show="!empty">
       <div :id="id"></div>
    </div>
</template>

<script setup>
import tool from "@/utils/tool";
import {
    echarts,
    echartunit,
    echartinit
} from "./commonLib.js";

const id = ref();

const empty = ref(false);

const chartRef = ref();
const init = async () => {
    await nextTick();
    chartRef.value = markRaw(echarts.init(document.getElementById(id.value)));
    chartRef.value.setOption(options);
    await echartinit(chartRef.value, id.value);
};

onMounted(() => {
    id.value = tool.energyUuid();
    init();
});

onUnmounted(() => {
    echartunit(id.value);
});
</script>

<style lang="less" scoped>
.box {
    height: 100%;
}
</style>
export const eContainerObserver = {
    echartInsArr: new Map(),
    observer(echartins, id) {
       // 开始时将图表保存
       let container = document.getElementsByClassName(id)[0]
       if (container && !this.echartInsArr.has(id)) {
          this.echartInsArr.set(id, echartins)
          this.resizeObserver.observe(container)
       }
    },
    unobserver(id) {
       // 某个图表销毁时要清理掉保存的图表
       let container = document.getElementsByClassName(id)[0]
       if (container) {
          this.resizeObserver.unobserver(container)
          this.echartInsArr.delete(id)
       }
    },
    resizeObserver: new ResizeObserver((entries, observer) => {
       let { par } = observer
       for (let entrie of entries) {
          let { target, contentRect } = entrie
          let id = entrie.target.classList[1]
          if (par.echartInsArr.has(id)) {
             let ins = par.echartInsArr.get(id)
             ins.resize({
                width: contentRect.width + 'px',
                height: contentRect.height + 'px'
             })
          }
       }
    })
//  创建Observer,回调函数中遍历echartInsArr中保存的图表,添加图表的大小重置处理逻辑,并且监控父元素大小变化
}
// 监视器工具对象
eContainerObserver.resizeObserver.par = eContainerObserver
// 方便回指

export async function echartinit(echartINS, id) {
    // 工具函数,处理图表初始化。
    await nextTick()
    let container = document.getElementsByClassName(id)[0]
    echartINS.resize({
       width: container.clientWidth + 'px',
       height: container.clientHeight + 'px'
    })
    eContainerObserver.observer(echartINS, id)
}
export async function echartunit(id) {
    // 处理图表卸载时的逻辑
    eContainerObserver.unobserver(id)
}