上一家公司的時候,有個頁面,有很多的echart。echart
圖形的形狀不一,需要很多的option
對象。當時我是搞了很多行的配置代碼,其實可以從配置抽離公共的部分寫在組件內部,不同的寫在父組件那里,這樣子就可以節省代碼。那時離職了,沒有時間做這個事情。心里一直記得這個事,剛好最近有空,就完成這個功能。
代碼如下。
<template>
<div :id="id" :style="style"></div>
</template>
<script>
import echarts from "echarts"
//如果有很多配置就使用map 映射吧
export default {
name: 'charts',
data () {
return {
chart: '',
//百度echart配置,難點是合並組件內部,父組件,和后台三方的數據,不過已經做到。
echartOption: this.propObj.option,
}
},
props: {
propObj: {
type: Object,
default(){
return {
//這里子組件需要接收父組件傳遞過來的參數
id: '',
width: '100%',
height: '100%',
option: {
title: {
text: 'ECharts 入門示例'
},
tooltip: {},
legend: {
data:['銷量']
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line'
}]
}
}
}
}
},
computed: {
style() {
return {
width: this.propObj.width,
height: this.propObj.height
}
}
},
watch: {
'propObj.option': {
handler(newVal, oldVal) {
this.echartOption = this.assignObj(oldVal,newVal)
this.change();
},
deep: true
}
},
mounted() {
this.init();
this.fetchChart();
},
methods: {
//獲取后台數據
fetchChart() {
let that = this;
let chartType = this._props.chart;
let yTitle = that.chartYAxisList[chartType];
$.get('/api/rpt/chartData', {chartType: this.chartTypeIdList[chartType], dataType: this.dataType}, function (result) {
if (result.code === 0) {
that.chartX = result.obj.xAxis;
that.xTitle = result.obj.xtitle;
that.chartData = result.obj.data;
let colors = '#' + Math.floor(Math.random() * 16777215).toString(16);
//合並最新配置
that.echartOption = that.assignObj(that.echartOption,{
xAxis: [{
name: that.xTitle,
data: that.chartX
}],
yAxis: [{
name: yTitle,
}],
series: [{
data: that.chartData,
lineStyle: {
normal: {
color:colors
}
},
itemStyle: {
normal: {
color: colors
}
}
}]
})
that.change();
}
})
},
//百度echart變化
change(){
if (this.chart) {
this.chart.setOption(this.echartOption)
} else {
this.init();
}
},
//百度echart初始化
init() {
this.chart = this.$echarts.init(document.getElementById(this.propObj.id))
this.chart.showLoading(); //開啟加載動畫
this.chart.setOption(this.echartOption)
this.chart.hideLoading(); //關閉加載動畫
window.addEventListener("resize", this.chart.resize());
},
//合並option的值、這份代碼很關鍵
assignObj(vm, firstSource) {
const callee = arguments.callee //將運行函數賦值給一個變量備用
for(let [index,item] of new Map([...arguments].map((item,i) => [i,item]))){
if(index === 0) continue; //躲開vm
let nextSource = [...arguments][index];
if (nextSource && typeof nextSource !== "object") continue;
Object.keys(vm).reduce((pre,cur) => { //如果想使用寬松模式,就把這一行的vm改為nextSource
if(Object.prototype.toString.call(vm[cur]) !== '[object Object]' && vm.hasOwnProperty(cur) && nextSource.hasOwnProperty(cur))
vm[cur] = nextSource[cur]
else if(Object.prototype.toString.call(vm[cur]) === '[object Object]' && vm.hasOwnProperty(cur) && nextSource.hasOwnProperty(cur))
callee(vm[cur],nextSource[cur]);
return vm;
},vm)
}
return vm
},
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
最后,歡迎關注我的公眾號。