VUE 单页面使用 echart 窗口变化时的用法
- 作者: 马桥红柳
- 来源: 51数据库
- 2021-08-06
在 vue 项目中,为了使 echart 在窗口变化时能够自适应,要用到 window.resize = function(){ .......};
但是我在项目刚开始的时间就有一个地方的高度变化使用了 window.resize ,在里面再次使用 会覆盖掉原来的,所以在里面图表使用时可以用
window.addeventlistener('resize',this.resizefu,false);
resixefu 就是图表变化时的方法
resizefu(){
let div = document.getelementbyid('changedata');
if(div && this.changedata.datatime.length>0){
this.chartsdiv.changedata.resize();
}
}
但里面有一个问题就是:每次进来当前页面都会执行 window.addeventlistener
解决方法是在路由勾子函数中把它给去掉,方法是
beforerouteleave(to, from, next) {
//页面走掉把事件给清除掉
window.removeeventlistener("resize", this.resizefu,false);
next()
},
补充知识:vue+echart图表自适应屏幕大小、点击侧边栏展开收缩图表自适应大小resize
开发中用到了echart图表,需要图表自适应大小resize,一开始使用的方法是:
window.onresize = function () {
this.mychart.resize();
};
但是又遇到一个问题,点击侧边栏的展开收起的时候,图表的大小没有自适应(因为窗口的大小没有变化)
这里参考vue+element+admin的框架写的自适应

一、index.vue的文件
引入chart图表``

这里是数据
chartdata: {
title: {
text: '3-1(2)',
textstyle: {
color: '#979797',
fontsize: 14
}
},
tooltip: {
trigger: 'axis'
},
legend: {
icon: 'rect',
itemwidth: 4, // 图例标记的图形宽度
itemheight: 11,
textstyle: {
lineheight: 65,
fontsize: 14
},
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containlabel: true
},
xaxis: {
type: 'category',
boundarygap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yaxis: {
type: 'value'
},
series: [
{
name: '邮件营销',
type: 'line',
stack: '总量',
data: [0, 132, 101, 134, 90, 230, 210]
},
{
name: '联盟广告',
type: 'line',
stack: '总量',
data: [220, 12, 191, 234, 20, 330, 10]
},
{
name: '视频广告',
type: 'line',
stack: '总量',
data: [15, 232, 201, 154, 190, 330, 110]
},
{
name: '直接访问',
type: 'line',
stack: '总量',
data: [320, 420, 301, 334, 60, 330, 320]
},
{
name: '搜索引擎',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
}
二、chart.vue
<template>
<div :class="classname" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
classname: {
type: string,
default: 'chart'
},
width: {
type: string,
default: '100%'
},
height: {
type: string,
default: '300px'
},
autoresize: {
type: boolean,
default: true
},
chartdata: {
type: object,
required: true
}
},
data() {
return {
chart: null
}
},
watch: {
chartdata: {
deep: true,
handler(val) {
this.setoptions(val)
}
}
},
mounted() {
this.$nexttick(() => {
this.initchart()
})
},
beforedestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initchart() {
this.chart = echarts.init(this.$el, 'macarons')
this.setoptions(this.chartdata)
},
setoptions(chartdata) {
this.chart.setoption(chartdata)
}
}
}
</script>
三、resize.js
import { debounce } from './debounce'
export default {
data() {
return {
$_sidebarelm: null
}
},
mounted() {
this.$_initresizeevent()
this.$_initsidebarresizeevent()
},
beforedestroy() {
this.$_destroyresizeevent()
this.$_destroysidebarresizeevent()
},
// to fixed bug when cached by keep-alive
// http://www.51sjk.com/Upload/Articles/1/0/265/265468_2021070801070310101.jpg
activated() {
this.$_initresizeevent()
this.$_initsidebarresizeevent()
},
deactivated() {
this.$_destroyresizeevent()
this.$_destroysidebarresizeevent()
},
methods: {
// use $_ for mixins properties
// http://www.all.com/files/Articles/416/0/210/210901_20210630114330827.html#private-property-names-essential
$_resizehandler() {
return debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)()
},
$_initresizeevent() {
window.addeventlistener('resize', this.$_resizehandler)
},
$_destroyresizeevent() {
window.removeeventlistener('resize', this.$_resizehandler)
},
$_sidebarresizehandler(e) {
if (e.propertyname === 'width') {
this.$_resizehandler()
}
},
$_initsidebarresizeevent() {
this.$_sidebarelm = document.getelementsbyclassname('sidebar-container')[0]
this.$_sidebarelm && this.$_sidebarelm.addeventlistener('transitionend', this.$_sidebarresizehandler)
},
$_destroysidebarresizeevent() {
this.$_sidebarelm && this.$_sidebarelm.removeeventlistener('transitionend', this.$_sidebarresizehandler)
}
}
}
四、debounce.js
/**
* @param {function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function() {
// 据上一次触发时间间隔
const last = +new date() - timestamp
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = settimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function(...args) {
context = this
timestamp = +new date()
const callnow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = settimeout(later, wait)
if (callnow) {
result = func.apply(context, args)
context = args = null
}
return result
}
}
以上这篇vue 单页面使用 echart 窗口变化时的用法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
