开发背景
新需求需要使用echarts和vue开发,在开发的过程中,发现网上已有的组件不符合自己的需求,所以准备自己开发一个。
经历了两版,第一版的写完之后每次传递给子组件的时候需要一堆数据,所以今天在第一版的基础上开发了第二版。
第一版
ecahrts组件
<template>
<div :id="id" :style="style" class="chartcom"></div>
</template>
<script>
export default {
name: 'chart',
data () {
return {
chart: ''
}
},
props: {
id: {
type: String
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '400px'
},
margin: {
type: String,
default: '0 auto'
},
option: {
type: Object,
default () {
return {
title: {
text: 'vue-Echarts'
},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子', 'tuoxie']
},
series: [
{
name: '销量',
type: 'line',
data: [5, 20, 36, 10, 10, 70]
}
]
}
}
}
},
// 在Chart.vue中加入watch
watch: {
// 观察option的变化
option: {
handler (newVal, oldVal) {
debugger
if (this.chart) {
if (newVal) {
this.chart.setOption(newVal)
} else {
this.chart.setOption(oldVal)
}
} else {
this.init()
}
},
deep: true // 对象内部属性的监听,关键。
}
},
computed: {
style () {
return {
height: this.height,
width: this.width,
margin: this.margin
}
}
},
mounted () {
this.init()
},
methods: {
init () {
this.chart = null
if (this.chart && this.chart.dispose) {
this.chart.dispose()
}
this.chart = this.$echarts.init(document.getElementById(this.id))
this.chart.setOption(this.option, true)
}
}
}
</script>
<style>
.chartcom {
background: #fff;
border-radius: 3px;
}
</style>
父组件使用
<chart id="test" :option="option" :height="height" :width="width"></chart>
option ,width,height是父组件传递给子组件的数据
option每次需要传很多数据,如果我需要在同一个父组件里使用好多个子组件,代码量就上来了,不好维护。
但是好处是,各种图例都适合。
第二版
组件代码
<template>
<div ref="chartline" class="chartcom"></div>
</template>
<script>
export default {
name: 'chart',
data () {
return {
chart: '',
normaloption: {
title: {
text: 'linechart'
},
tooltip: {
trigger: 'axis'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
yAxis: [
{
show: true,
type: 'value'
}
],
legend: {
data: this.option.ldata
},
xAxis: {
data: this.option.xdata
},
series: this.option.sdata
}
}
},
props: {
option: {
type: Object,
default () {
return {
ldata: [1, 2, 3],
xdata: [],
sdata: []
}
}
}
},
// 在Chart.vue中加入watch
watch: {
// 观察option的变化
option: {
handler (newVal, oldVal) {
if (newVal) {
this.normaloption.legend.data = newVal.ldata
this.normaloption.xAxis.data = newVal.xdata
this.normaloption.series = newVal.sdata
this.init()
// this.chart.setOption(this.normaloption)
} else {
this.normaloption.legend.data = oldVal.ldata
this.normaloption.xAxis.data = oldVal.xdata
this.normaloption.series = oldVal.sdata
this.init()
// this.chart.setOption(this.normaloption)
}
},
deep: true // 对象内部属性的监听,关键。
}
},
computed: {
},
mounted () {
// this.init()
},
methods: {
init () {
this.chart = this.$echarts.init(this.$refs.chartline)
this.chart.setOption(this.normaloption, true)
}
}
}
</script>
<style>
.chartcom {
background: #fff;
border-radius: 3px;
height: 400px;
}
</style>
子组件使用
<chart :option='bardata'></chart>
bardata 里面只要传接口拿到的数据就好,不需要传一些多余的东西。
但是缺点是,针对饼图和线图,需要单独封装,不能共用。
仍然遗留了一个问题,
window.addEventListener('resize',function() {
this.chart.resize()
}