VUE 單頁面使用 echart 視窗變化時的用法
阿新 • • 發佈:2020-07-31
在 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",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: '聯盟廣告',data: [220,12,191,234,20,330,10] },{ name: '視訊廣告',data: [15,232,201,154,190,110] },{ name: '直接訪問',data: [320,420,301,334,60,320] },{ name: '搜尋引擎',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 // https://github.com/PanJiaChen/vue-element-admin/issues/2116 activated() { this.$_initResizeEvent() this.$_initSidebarResizeEvent() },deactivated() { this.$_destroyResizeEvent() this.$_destroySidebarResizeEvent() },methods: { // use $_ for mixins properties // https://vuejs.org/v2/style-guide/index.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',$_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 視窗變化時的用法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。