echarts图表的自适应有两种方案
1.通过window.onresize api 监听页面视口大小改变时,自适应变化(echarts.resize())
2.通过ResizeObserver api 监听组装echarts容器的大小,自适应变化(echarts.resize())
两种方式各有优缺点,
window.onresize 兼容性好,但是只能根据视口改变才能自适应。假如当组装echarts的容器大小改变但是页面视口并没有改变是无法自适应的。比如后台管理页面,侧边栏伸缩展开时。比如父组件大小是卡片可以拉拽调整大小
ResizeObserver 是有兼容性问题。他能够监听指定父容器的大小来进行自适应。也有其他补充方法可以解决兼容性问题。
以下是ResizeObserver 的解决方案。
this.resizeObserver.observe 调用的时机十分重要,不然会出错
<template>
<div ref="myChart" :class="className" :style="{ height: height, width: width }" :option="option" />
</template>
<script>
import { debounce } from "@/core/util/util";
export default {
props: {
className: { type: String, default: "chart", },
width: { type: String, default: "100%", },
height: { type: String, default: "100%", },
option: { type: Object, required: true, default: () => ({}), }
},
data() {
return {
instance: null,
resizeObserver: null,
};
},
mounted() {
this.initChart();
},
beforeDestroy() {
if (!this.instance) return;
this.disposeResizeObserver()
this.disposeChart()
this.resizeObserver = null
this.instance = null;
},
methods: {
// 初始化Chart
initChart() {
if (this.instance) return;
this.disposeChart();
this.disposeResizeObserver();
this.instance = window.echarts.init(this.$refs.myChart)
this.initResizeObserver()
},
// 加载表格
loadChart() {
this.instance?.setOption(this.option, true); //设置为true时不会合并数据,而是重新刷新数据
this.resizeObserver && this.instance?.on('finished', () => this.loadResizeObserver());
},
// 销毁Chart
disposeChart() {
this.instance?.dispose();
},
// 初始化ResizeObserver
initResizeObserver() {
if (!this.instance) return;
const __resizeHandler = debounce(() => {
this.instance?.resize()
}, 100)
this.resizeObserver = new ResizeObserver((entries, observer) => {
__resizeHandler();
});
},
// 开启监视ResizeObserver
loadResizeObserver() {
this.resizeObserver?.observe(this.$refs.myChart);
},
// 销毁ResizeObserver
disposeResizeObserver() {
this.resizeObserver?.unobserve(this.$refs.myChart);
this.resizeObserver?.disconnect()
},
},
watch: {
option: {
// immediate:true,
deep: true,
handler() {
this.loadChart();
},
},
},
};
</script>