前言
前端图表经常要进行 resize 操作,一般我们会想到监听 window resize event, 但是这个事件只能监听 window 窗口大小的改变, 没有办法监听到某个div大小的改变
目前解决方案
ResizeObserver
下面是使用的例子
const resizeObserver = new ResizeObserver((enties, observer)=> {
// 这里可以拿到观察的所有实体
});
const elem = document.querySelect('a');
// 观察 elem 这个元素
resizeObserver.observer(elem);
ResizeObserver 有兼容问题,但是我们可以用 resize-observer-polyfill
npm install resize-observer-polyfill --save
yarn add resize-observer-polyfill --save
下面看一个完整的例子 echart.vue
<template>
<div class="chart-container" ref="chart"></div>
</template>
<script>
import Vue from 'vue';
import ResizeObserver from 'resize-observer-polyfill';
import throttle from 'lodash/throttle';
const echarts = require('echarts');
Vue.prototype.$echarts = echarts;
let resizeObserver = null;
export default {
name: 'VEchart',
props: {
theme: String,
options: {
type: Object,
default() {
return null;
},
isLoading: {
type: Boolean,
default: false,
},
},
},
data() {
return {
instance: null,
};
},
watch: {
options(val) {
if (val) {
this.refresh(val);
}
},
isLoading(val) {
this.initChart();
if (val) {
this.instance.showLoading();
} else {
this.instance.hideLoading();
}
},
},
methods: {
// init chart
initChart() {
this.instance = this.instance || this.$echarts.init(this.$refs.chart);
},
// 获取chart 实例
getInstance() {
this.initChart();
return this.instance;
},
// 获取现有的 options
getOption() {
return this.getInstance.getOption();
},
// 刷新chart
refresh(options, notMerge = false) {
this.initChart();
this.instance.setOption(options || this.options, notMerge);
},
// bind resize
bindResize() {
const deboundResize = throttle(() => {
this.instance && this.instance.resize();
}, 250);
resizeObserver = new ResizeObserver((entries, observer) => {
deboundResize();
});
resizeObserver.observe(this.$refs.chart);
},
// 解绑 resize
unbindResize() {
resizeObserver.unobserve(this.$refs.chart);
},
},
mounted() {
this.bindResize();
},
beforeDestroy() {
// 销毁组件时,解绑 reszie
this.unbindResize();
},
};
</script>
<style scoped></style>