在Vue中封裝Echarts并使用
- 為什么要封裝
- 效果圖以及專案目錄
- 1、效果圖
- 2、專案目錄
- 具體封裝程序
- 1、Echarts的安裝
- 2、引入
- 3、封裝案例
- 4、使用組件的頁面
- 5、使用mixins解決resize問題
- 6、element-resize-detector
- 寫在最后
為什么要封裝
- 如果不封裝,每用一次圖表,都要重新配置一邊option,封裝起來方便復用,也方便統一管理,
- 解決元素以及視窗的resize等問題,
- 自己動手封裝,只需要看一份檔案,并且可以使用更多的原生功能,
- 看完這篇文章你或許覺得自己封裝并不難,
效果圖以及專案目錄
1、效果圖

2、專案目錄

具體封裝程序
1、Echarts的安裝
npm i echarts --save
2、引入
- 全部引入
在你使用Echarts的.vue單檔案直接使用以下陳述句引入:
import echarts from 'echarts'
- 按需引入
圖省事可以整個引入,但是Echarts還是不小的,我們大部分只用到了其中的一部分功能,所以我推薦按需引入:
// 按需引入 引入 ECharts 主模塊
var echarts = require('echarts/lib/echarts')
// 引入柱狀圖
require('echarts/lib/chart/pie')
// 引入提示框和標題組件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
require('echarts/lib/component/legend')
如果你想用某個組件,但是不清楚該組件屬于Echarts的哪一個組成部分,這時你可以查閱檔案,點進去滑鼠往下翻兩下就可以簡單下面這張圖了,里面說的也比較清楚:

3、封裝案例
此處以堆疊柱狀圖為例:BarChart.vue
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
// 按需引入 引入 ECharts 主模塊
var echarts = require('echarts/lib/echarts')
// 引入柱狀圖
require('echarts/lib/chart/bar')
// 引入提示框和標題組件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
import chartResize from './mixins/chart-resize'
export default {
mixins:[chartResize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
// 父組件傳遞過來的圖表資料
chartData: {
type: Object,
required: true
}
},
data() {
return {
// Echarts實體
chart: null
}
},
watch: {
/* 如果圖表資料是后臺獲取的,監聽父組件中的資料變化,重新觸發Echarts */
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
},
mounted() {
/* 圖表初始化 */
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
/* 釋放圖表實體 */
this.chart.dispose()
/* dispose 會釋放內部占用的一些資源和事件系結,但是解除實體的參考我們是做不到的,所以需要重新賦值為null */
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el)
this.setOptions(this.chartData)
},
setOptions({ days, data1, data2 } = {}) {
this.chart.setOption({
title: {
text: '堆疊柱狀圖',
textStyle: {
fontSize: 15
}
},
tooltip: {
trigger: 'axis',
axisPointer: { // 坐標軸指示器,坐標軸觸發有效
type: 'shadow' // 默認為直線,可選為:'line' | 'shadow'
}
},
grid: {
top: 35,
left: '2%',
right: '2%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: days,
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value',
axisTick: {
show: false
}
}],
series: [{
name: '數量一',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: data1,
animationDuration:2000
},
{
name: '數量二',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: data2,
animationDuration:2000
}]
})
}
}
}
</script>
- 在實際的情況當中,我們使用的圖表資料一般都是從后臺動態獲取的,我們就需要對父組件傳遞過來的chartData進行監聽,資料變化時,觸發Echarts,進行視圖的更新:
watch: {
/* 如果圖表資料是后臺獲取的,監聽父組件中的資料變化,重新觸發Echarts */
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
}
- 在組件銷毀時,請不要忘記以下操作,釋放一定的記憶體空間:
beforeDestroy() {
if (!this.chart) {
return
}
/* 釋放圖表實體 */
this.chart.dispose()
/* dispose 會釋放內部占用的一些資源和事件系結,但是解除實體的參考我們是做不到的,所以需要重新賦值為null */
this.chart = null
},
4、使用組件的頁面
index.vue
<template>
<div id="echarts-container">
<el-row :gutter="20">
<el-col :span="12">
<div class="grid-content bg-purple">
<bar-chart :chartData="barChartData"/>
</div>
</el-col>
<el-col :span="12">
<div class="grid-content bg-purple">
<rose-chart />
</div>
</el-col>
</el-row>
<el-row style="background-color:#fff">
<line-chart :chartData="lineChartData" />
</el-row>
</div>
</template>
<script>
// 引入組件
import BarChart from './components/BarChart'
import RoseChart from './components/RoseChart'
import LineChart from './components/LineChart'
export default {
// 注冊區域組件
components:{
BarChart,
RoseChart,
LineChart
},
data() {
return {
// 柱狀圖資料
barChartData: {
days: ['11.21', '11.22', '11.23', '11.24', '11.25', '11.26', '11.27'],
data1: [100, 120, 161, 134, 105, 160, 165],
data2: [120, 82, 91, 154, 162, 140, 145]
},
// 折線圖資料
lineChartData: {
expectedData: [4, 9, 12, 11, 5, 2, 9],
actualData: [10, 4, 3, 11, 13, 10, 7]
}
}
}
}
</script>
<style lang="less" scoped>
#echarts-container{
width: 100%;
height: 100%;
background-color: #F0F2F5;
.el-row {
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
}
.el-col {
border-radius: 4px;
}
.bg-purple-dark {
background: #99a9bf;
}
.bg-purple {
background: #fff;
}
.bg-purple-light {
background: #e5e9f2;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
.row-bg {
padding: 10px 0;
background-color: #f9fafc;
}
}
</style>
- 在這個頁面簡單的使用了Element-UI的柵格布局,
- 在使用自己封裝的Echarts組件時,也進行了資料的傳入,
5、使用mixins解決resize問題
Echarts有更新資料的特性,以及視窗縮放時不能自適應的問題,這樣導致資料更新了Echarts視圖卻沒有更新,視窗縮放引起echarts圖形變形問題,如下:
視窗變化,但是視圖卻沒有自適應,就導致出現顯示的問題,

但是使用了自定義的mixins之后,可以隨著視窗的變化而自適應:

自定義的mixins代碼如下:chart-resize.js
import ResizeListener from 'element-resize-detector';
export default {
methods: {
/* 對chart元素尺寸進行監聽,當發生變化時同步更新echart視圖 */
chartEleResizeListener() {
const chartInstance = ResizeListener({
strategy: 'scroll',
callOnAdd: true
});
chartInstance.listenTo(this.$el, () => {
if (!this.chart) return;
this.chart.resize();
});
},
/* 當視窗縮放時,echart動態調整自身大小 */
windowResizeListener() {
if (!this.chart) return;
this.chart.resize();
}
},
mounted() {
window.addEventListener('resize', this.windowResizeListener);
this.chartEleResizeListener();
},
beforeDestroy() {
window.removeEventListener('resize', this.windowResizeListener);
}
}
6、element-resize-detector
是一個監聽元素大小改變的插件,除了視窗的大小改變會引起變形之外,echart實體的父元素大小改變也會使其變形,所以我們還要對其父元素大小改變進行監聽,做到完全的自適應,
寫在最后
如有不足,歡迎指正,
對原始碼感興趣歡迎訪問我的github,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/243282.html
標籤:其他
