有關後臺管理系統以前寫過三遍博客,看這篇以前最好先看下這三篇博客。另外這裏只展現關鍵部分代碼,項目代碼放在github上: mall-manage-systemjavascript
一、Vue + Element-ui實現後臺管理系統(1) --- 總述css
二、Vue + Element-ui實現後臺管理系統(2) --- 項目搭建 + ⾸⻚佈局實現html
三、Vue + Element-ui實現後臺管理系統(3) --- 麪包屑 + Tag標籤切換功能vue
這篇主要講解實現圖表的功能:java
總體效果
git
ECharts上手很是簡單,具體簡單示例能夠參考我以前寫的一篇博客:圖表工具--- ECharts.js學習(一) 簡單入門。github
在實際項目開發中,咱們會常常與圖表打交道,好比 訂單數量表、商品銷量表、會員數量表等等,它多是以折線圖、柱狀圖、餅狀圖等等的方式來展示。小程序
若是咱們沒有封裝組件的思想的話,那麼咱們每次須要畫一個圖表都要重複相似相同的工做,並且代碼看去很是冗餘。因此咱們就須要考慮封裝一個ECharts組件,這個組件經過接收echarts
不一樣的數據來渲染成不一樣的圖表,之後當須要生成一張圖表的時候,只須要把相關的數據傳入到這個組件中,就會渲染對應的圖表。ide
而這裏的核心就是 哪些數據是須要咱們傳入組件中的。針對這個問題咱們來看下一個ECharts最簡單的示例
// 指定圖表的配置項和數據 var option = { title: { text: 'ECharts 入門示例' }, tooltip: {}, legend: { data:['銷量'] }, xAxis: { data: ["襯衫","羊毛衫","雪紡衫","褲子","高跟鞋","襪子"] }, yAxis: {}, series: [{ name: '銷量', type: 'bar', data: [5, 20, 36, 10, 10, 20] }] };
運行結果
這裏展現了一個最簡單的圖表,官方例子地址:5 分鐘上手 ECharts,下面對這些參數作個講解
title : 標題
tooltip : 提示框組件
legend : 圖例組件
xAxis : 直角座標軸中的 x 軸
yAxis : 直角座標軸中的 y 軸
series : 系列列表。每一個系列經過 type 決定本身的圖表類型
這幾個組件來看 series
和 xAxis
是確定須要外部傳來的數據,y軸 的數據跟series中data相關不須要單獨再傳。至於title , tooltip , legend並非圖表必須的,因此
不是必需要傳的。就比如你一個圖表你能夠沒有標題。
注意
這裏還有一點 x軸對於柱狀圖、折線圖相關圖是必定要有的,但對於餅狀圖來說它又不是必須的,因此這裏封裝一個ECharts組件時,須要考慮這一點。
新建一個EChart.vue,做爲封裝ECharts的組件
<template> <!--圖表展現在這個div中--> <div style="height: 100%" ref="echart"> echart </div> </template> <script> import echarts from 'echarts' export default { //接收父類兩個數據 一、chartData (series數據 + x座標系數據)二、isAxisChart (是否有x座標系,若是false,那麼上面的xData就爲空) props: { chartData: { type: Object, default() { return { xData: [], series: [] } } }, isAxisChart: { //默認type爲true 就表明默認是有x軸的 type: Boolean, default: true } }, computed: { //計算 選擇是有x軸 仍是沒有x軸的數據 options() { return this.isAxisChart ? this.axisOption : this.normalOption }, //用於下面的resize 改變圖表尺寸,在容器大小發生改變時須要手動調用 isCollapse() { return this.$store.state.tab.isCollapse } }, watch: { //監聽chartData數據 chartData: { handler: function() { this.initChart() }, deep: true }, //監聽isCollapse 由於頭部水平擴展是一個動畫須要時間,因此這裏延遲300毫秒 isCollapse() { setTimeout(() => { this.resizeChart() }, 300) } }, data() { //在數據中有些數據在數據件中是寫死的 return { echart: null, axisOption: { legend: { textStyle: { color: '#333' } }, grid: { left: '20%' }, tooltip: { trigger: 'axis' }, xAxis: { type: 'category', data: [], axisLine: { lineStyle: { color: '#17b3a3' } }, axisLabel: { color: '#333' } }, yAxis: [ { type: 'value', axisLine: { lineStyle: { color: '#17b3a3' } } } ], color: [ '#2ec7c9', '#b6a2de', '#5ab1ef', '#ffb980', '#d87a80', '#8d98b3', '#e5cf0d', '#97b552', '#95706d', '#dc69aa', '#07a2a4', '#9a7fd1', '#588dd5' ], series: [] }, normalOption: { tooltip: { trigger: 'item' }, color: ['#0f78f4', '#dd536b', '#9462e5', '#a6a6a6', '#e1bb22', '#39c362', '#3ed1cf'], series: [] } } }, methods: { initChart() { //獲取處理好的數據 this.initChartData() //獲取echart對象 if (this.echart) { this.echart.setOption(this.options) } else { //經過refs獲取 this.echart = echarts.init(this.$refs.echart) this.echart.setOption(this.options) } }, //處理好數據 initChartData() { if (this.isAxisChart) { this.axisOption.xAxis.data = this.chartData.xData this.axisOption.series = this.chartData.series } else { this.normalOption.series = this.chartData.series } }, resizeChart() { this.echart ? this.echart.resize() : '' } }, mounted() { //resize 改變圖表尺寸,在容器大小發生改變時須要手動調用(由於側邊欄是能夠收縮的,因此這裏圖表根據是否收縮來改變圖表尺寸) window.addEventListener('resize', this.resizeChart) }, //銷燬 防止內存泄漏 destroyed() { window.removeEventListener('resize', this.resizeChart) } } </script> <style lang="scss" scoped></style>
這樣一個簡單的公共組件就完成了,接下來咱們經過傳入不一樣的數據到這個組件來渲染不一樣的圖表。
咱們看到在首頁有三個圖表,那咱們這裏就要組裝三種不一樣的數據,傳入到EChart.vue組件中,來生成不一樣的圖表。
<template> <div> <!--圖表一 這裏的數據是折線圖--> <echart style="height: 280px" :chartData="echartData.order"></echart> <!--圖表二 這裏的數據是柱狀圖--> <echart :chartData="echartData.user" style="height: 260px"></echart> <!--圖表三 這裏的數據是餅狀圖 由於餅狀圖是不用x軸的 因此這裏isAxisChart爲false--> <echart :chartData="echartData.video" style="height: 260px" :isAxisChart="false"> </div> </template> <script> import Echart from '../../components/EChart' export default { components: { Echart }, data() { return { echartData: { //圖一 order: { xData: [], series: [] }, //圖二 user: { xData: [], series: [] }, //圖三 餅狀圖沒有x軸 mall: { series: [] } } } }, methods: { getTableData() { this.$http.get('/home/getData').then(res => { res = res.data // 訂單折線圖 const order = res.data.orderData //x軸數據 爲日前 this.echartData.order.xData = order.date // 第一步取出series中的name部分——小米,三星、蘋果... let keyArray = Object.keys(order.data[0]) // 第二步,循環添加數據 keyArray.forEach(key => { this.echartData.order.series.push({ //若是有須要還能夠作一步抓換好比:後臺返回性別是一、2。那這裏key === 1 ? '男' : 女, name: key === 'wechat' ? '小程序' : key, data: order.data.map(item => item[key]), type: 'line' }) }) // 用戶柱狀圖 this.echartData.user.xData = res.data.userData.map(item => item.date) this.echartData.user.series.push({ name: '新增用戶', data: res.data.userData.map(item => item.new), type: 'bar' }) this.echartData.user.series.push({ name: '活躍用戶', data: res.data.userData.map(item => item.active), type: 'bar', barGap: 0 }) // 商品餅圖 this.echartData.mall.series.push({ data: res.data.mallData, type: 'pie' }) }) } }, created() { this.getTableData() } } </script>
大體的思路就是這樣的,若是你想在組件中加入title等參數,那也能夠修改下這個組件就能夠了。
總結下封裝組件的基本思路
一、觀察⽂檔,考慮組件須要的基本參數 二、參數篩選,分爲從⽗組件傳來的參數和⾃身的參數 三、完善組件,觀察設計圖,找不一樣,在⽂檔中尋找對應的配置項 四、細節優化,考慮多種場景下,圖表⾃適應的處理
別人罵我胖,我會生氣,由於我內心認可了我胖。別人說我矮,我就會以爲可笑,由於我內心知道我不可能矮。這就是咱們爲何會對別人的攻擊生氣。 攻我盾者,乃我心裏之矛(14)