在Vue中封装Echarts并使用
为什么要封装
- 如果不封装,每用一次图表,都要重新配置一边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.jsimport 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实例的
父元素大小改变也会使其变形,所以我们还要对其父元素大小改变进行监听,做到完全的自适应。
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>
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126在实际的情况当中,我们使用的图表数据一般都是从后台动态获取的,我们就需要对父组件传递过来的chartData进行监听,数据变化时,触发Echarts,进行视图的更新:watch: {/* 如果图表数据是后台获取的,监听父组件中的数据变化,重新触发Echarts */chartData: { deep: true, handler(val) { this.setOptions(val) }}}123456789在组件销毁时,请不要忘记以下操作,释放一定的内存空间:beforeDestroy() { if (!this.chart) { return } /* 释放图表实例 */ this.chart.dispose() /* dispose 会释放内部占用的一些资源和事件绑定,但是解除实例的引用我们是做不到的,所以需要重新赋值为null */ this.chart = null },1234567894、使用组件的页面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>123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081在这个页面简单的使用了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); }}12345678910111213141516171819202122232425262728296、element-resize-detector是一个监听元素大小改变的插件,除了窗口的大小改变会引起变形之外,echart实例的父元素大小改变也会使其变形,所以我们还要对其父元素大小改变进行监听,做到完全的自适应。————————————————版权声明:本文为CSDN博主「一羊迁徙」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_43242112/article/details/112016207





浙公网安备 33010602011771号