在Vue中使用Echarts

在Vue中使用Echarts

实际的Vue项目开发中可能需要用到Echarts来制作图表。本文将分享在VueCli3中使用Echarts的小经验。

环境配置

安装

echartsvue-echarts ( vue-echarts是基于echarts封装实现的一个组件库)

1
npm i echarts vue-echarts --save

引入

main.js中导入包

1
2
3
4
import ECharts from 'vue-echarts'
import echarts from 'echarts'
Vue.component('chart', ECharts)
Vue.prototype.$echarts = echarts

引入一些echarts中比较常用的模块,其他主要模块到使用的组件内按需引入

1
2
3
4
import "echarts/lib/chart/bar";
import "echarts/lib/component/tooltip";
import "echarts/lib/component/legend";
import "echarts/lib/component/title";

使用相关

基本使用

使用注册的全局组件chart即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<chart :options="options" :auto-resize="true"></chart>
</template>

<script>
import 'echarts/lib/chart/line' //加入折现表
export default {
data () {
return {
options:{} //设置echarts中的参数options
}
}
}
</script>

更为优雅的使用

由于实际开发时可能遇到不同的数据格式。我比较推荐将图表封装为一个与项目中实际数据结构相同的组件。

options的数据结构可以参考官网 https://www.echartsjs.com/zh/option.html#title

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<template>
<chart :options="options" :auto-resize="true"></chart>
</template>

<script>
import 'echarts/lib/chart/line'
export default {
props:{
title:String, //图表标题
Cats:Array, //对象数组{name:String,data:[]}
xData:Array //x轴的标记
},
data () {
return {
options:{}
}
},
created(){
this.options = {
title: {
left:'center',
top:"0",
text: this.title
},
tooltip: {
trigger: 'axis'
},
legend: {
top:"40",
data: this.Cats.map(e=>e.name)
},
grid: {
left: '3%',
right: '4%',
top: '20%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: this.xData
},
yAxis: {
type: 'value'
},
series: this.Cats.map(e => {e.type = "line";return e})
}
}
}
</script>

<style lang="scss" scoped>

</style>

遇到的问题

图表中的数据是由后端获取的,那么当图表绘制完成后,由于图表options中有些数据比较深,更新时可能会发生数据监听不到的问题。

我的解决办法是在在组件中加入一个vue侦听,侦听要发生变化的变量,例如上例中我加入了watch来侦听会发生变化的属性Cats

1
2
3
4
5
6
watch:{
Cats(newValue){
this.$set(this.options,'series',newValue.map(e => {e.type = "line";return e}))
this.$set(this.options.legend,'data',newValue.map(e=>e.name))
}
}

完整代码与效果

折线图

数据结构内容说明

组件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<template>
<chart :options="options" :auto-resize="true"></chart>
</template>

<script>
import 'echarts/lib/chart/line'
export default {
props:{
title:String,
Cats:Array,
xData:Array
},
data () {
return {
options:{}
}
},
created(){
this.options = {
title: {
left:'center',
top:"0",
text: this.title
},
tooltip: {
trigger: 'axis'
},
legend: {
top:"40",
data: this.Cats.map(e=>e.name)
},
grid: {
left: '3%',
right: '4%',
top: '20%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: this.xData
},
yAxis: {
type: 'value'
},
series: this.Cats.map(e => {e.type = "line";return e})
}
},
watch:{
Cats(newValue){
this.$set(this.options,'series',newValue.map(e => {e.type = "line";return e}))
this.$set(this.options.legend,'data',newValue.map(e=>e.name))
}
}
}
</script>

<style lang="scss" scoped>

</style>

运行效果

饼图

数据结构内容说明

组件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<template>
<chart ref="charts" :options="options" :auto-resize="true"></chart>
</template>

<script>
import 'echarts/lib/chart/pie'
import "echarts/lib/component/legendScroll";
export default {
props:{
title:String,
Cats:Array
},
computed: {
CatsName(){
return this.Cats.map(e=>e.name)
}
},
data () {
return {
options:{}
}
},
mounted(){
this.options={
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
type:'scroll',
orient: 'vertical',
left: 2,
top: 20,
height:140,
},
title: [{
left: 'center',
text: this.title
}],
series: [
{
name: '访问量',
type: 'pie',
radius: '63%',
left:150,
avoidLabelOverlap: false,
label: {
normal: {
show: true,
position: 'top'
},
},
labelLine: {
normal: {
show: true
}
},
}
]
}
},
watch:{
Cats(newValue){
this.$set(this.options.series[0],'data',newValue)
this.$set(this.options.legend,'data',this.CatsName)
}
}
}
</script>

<style lang="scss" scoped>

</style>

运行效果

0%