使用Vue+DataV+Echarts打造新冠肺炎疫情數據大屏(可動態刷新)
原文地址:使用Vue+DataV+Echarts打造新冠肺炎疫情數據大屏(可動態刷新)
源碼
查看:https://blog.lanweihong.com/posts/29267/
效果圖
演示
僅適配 1080P 屏幕,使用瀏覽器訪問后按 F11 進入全屏可看最佳顯示效果。
疫情真實數據演示地址:演示地址-真實數據
模擬數據演示地址:演示地址-模擬數據
前端框架和類庫
Vue.js
Apache ECharts
DataV
axios
Element
Mock
代碼實現
創建項目
使用 Vue Cli 創建 Vue 項目,沒有 Vue Cli 的使用以下命令安裝:
npm install -g @vue/cli
創建項目:
vue create datav-covid-19
安裝依賴
# 安裝 DataV npm install @jiaminghi/data-view # 安裝 echarts npm install echarts -S # 安裝 element-ui npm i element-ui -S # 安裝 vue-router npm install vue-router # 安裝 mockjs npm install mockjs --save-dev # 安裝 axios npm install axios # 安裝 echarts-liquidfill npm i echarts-liquidfill
引入注冊
在項目中引入,編輯 main.js:
import Vue from 'vue' import App from './App.vue' import dataV from '@jiaminghi/data-view' import * as echarts from 'echarts' import 'element-ui/lib/theme-chalk/index.css'; import axios from 'axios' // 引入 echarts 水球圖 import 'echarts-liquidfill' import VueRouter from 'vue-router' import { Icon, Row, Col, Table, TableColumn, Button, Dialog, Link } from 'element-ui'; // 注冊 echarts Vue.prototype.$echarts = echarts Vue.config.productionTip = false // 注冊 axios Vue.prototype.axios = axios // 注冊 dataV Vue.use(dataV) // 注冊路由 Vue.use(VueRouter) // 按需注冊其他 element-ui 組件 Vue.use(Icon) Vue.use(Row) Vue.use(Col) Vue.use(Table) Vue.use(TableColumn) Vue.use(Button) Vue.use(Dialog) Vue.use(Link) new Vue({ render: h => h(App), }).$mount('#app')
編寫組件
因為篇幅有限,為了閱讀體驗,這里以 累計排名 組件為例,其他的組件請看 Github 上的代碼。
效果圖
累計排名組件采用 ECharts 的柱狀圖來顯示,實現代碼如下:
在頁面中引入使用:
其他組件的代碼就不在這里寫了,完整代碼已上傳 Github ,需要的可以去查看。
完整的組件結構如下:
準備模擬數據
項目中提供了兩種數據提供方式,一是請求真實后臺地址,返回的數據格式參考 data 目錄下的 json 文件;二是在本地使用 Mock 生成模擬數據。這里僅介紹使用 Mock 生成模擬數據方式。
在項目根目錄下創建文件夾 mock,分別創建 covid19.js 和 index.js;
covid19.js 代碼如下,代碼中使用到一些 Mock 的語法,具體使用方法請查看 Mock 的文檔。
// 從本地讀取 json 數據 const provinceData = require('../data/covid19-province.json') const dailyData = require('../data/covid19-daily-list.json') // 引入 mockjs const Mock = require('mockjs') // 使用 mockjs 的 Random 生成隨機數據 const Random = Mock.Random module.exports = [ { url: '/api/covid-19/overall', type: 'get', response: config => { return { success: true, code: 200, message: "操作成功", data: { confirmedCount: Random.integer(110000, 120000), confirmedIncr: 72, curedCount: Random.integer(100000, 110000), curedIncr: 173, currentConfirmedCount: Random.integer(3000, 4000), currentConfirmedIncr: -110, deadCount: Random.integer(4000, 6000), deadIncr: 12, importedCount: Random.integer(6000, 8000), importedIncr: 23, noInFectCount: Random.integer(400, 600), noInFectIncr: 8, suspectIncr: 0, suspectCount: 2, updateTime: "2021-07-15 20:39:11", curedRate: Random.float(90, 95, 0, 9), deadRate: Random.float(1, 5, 0, 9) } } } }, { url: '/api/covid-19/area/latest/list', type: 'get', response: config => { return provinceData } }, { url: '/api/covid-19/list', type: 'get', response: config => { return dailyData } } ]
編輯 index.js,這里主要是注冊 mock 服務,調用方法 initMockData() 完成注冊;
const Mock = require('mockjs') // 引入寫好的 mock 服務 const covid19 = require('./covid19') const mocks = [ ...covid19 ] function param2Obj(url) { const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') if (!search) { return {} } const obj = {} const searchArr = search.split('&') searchArr.forEach(v => { const index = v.indexOf('=') if (index !== -1) { const name = v.substring(0, index) const val = v.substring(index + 1, v.length) obj[name] = val } }) return obj } const initMockData = () => { Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send Mock.XHR.prototype.send = function() { if (this.custom.xhr) { this.custom.xhr.withCredentials = this.withCredentials || false if (this.responseType) { this.custom.xhr.responseType = this.responseType } } this.proxy_send(...arguments) } function XHR2ExpressReqWrap(respond) { return function(options) { let result = null if (respond instanceof Function) { const { body, type, url } = options result = respond({ method: type, body: JSON.parse(body), query: param2Obj(url) }) } else { result = respond } return Mock.mock(result) } } for (const i of mocks) { Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) } } module.exports = { mocks, initMockData }
在 main.js 中引入:
const { initMockData } = require('../mock') // 完成注冊 initMockData()
然后在頁面中使用 request.get('/api/covid-19/list') 就能請求獲取到數據,這里的 request.get() 是我用 axios 封裝寫的方法。
封裝數據接口
項目中的數據請求都是使用 axios 為方便使用,我簡單封裝了一個工具類 request.js:
import axios from "axios" import sysConst from '../libs/const' const fetch = (method = 'GET', url, param = '') => { // 處理 url url = `${sysConst.baseUrl}${url}` return new Promise((resolve, reject) => { axios({ method: method, url: url, changeOrigin: true, data: JSON.stringify(param) }).then((res) => { resolve(res.data) }, error => { reject(error) }).catch((error) => { reject(error) }) }) } const get = (url) => { return fetch('GET', url) } const post = (url, data) => { return fetch('POST', url, data) } const put = (url, data) => { return fetch('PUT', url, data) } const remove = (url, data) => { return fetch('DELETE', url, data) } export { get, post, put, remove }
這里引入的 const.js 代碼如下:
let baseUrl = '' if (process.env.NODE_ENV === 'development') { // 修改你的 API 地址 baseUrl = '' } else { // 你的 API 地址 baseUrl = '' } export default { baseUrl }
在項目根目錄下新建文件夾 api ,用于保存編寫數據接口,在該目錄下新增文件 covid19.js,用于封裝請求獲取數據:
import * as request from '@/utils/request' /** * 接口封裝 */ export default { getOverall() { let url = `/api/covid-19/overall?_=${Math.random()}` return request.get(url) }, getProvinceDataList() { let url = `/api/covid-19/area/latest/list?_=${Math.random()}` return request.get(url) }, getDailyList() { let url = `/api/covid-19/list?t=${Math.random()}` return request.get(url) } }
調用數據接口獲取數據并更新圖表展示
// 引入 import covid19Service from '../api/covid19' // 使用 let self = this covid19Service.getOverall().then((res) => { if (!res.success) { console.log('錯誤:' + res.info) return } // 修改數據,圖表組件檢測到數據變化會觸發 setOptions() 方法更新顯示( setOptions() 在圖表組件中已定義好) self.basicData = res.data })
項目結構
完整的項目結構如下:
├─build ├─data # 本地模擬數據目錄 ├─mock # mock 配置 ├─public └─src ├─api # 接口封裝目錄 ├─assets ├─components # 組件目錄 │ ├─About # 關于 │ ├─BasicDataItemLabel # 基本數據顯示標簽 │ ├─BasicProportionChart # 占比圖表 │ ├─BasicTrendChart # 趨勢圖表 │ ├─ChartCard # 圖表面板 │ ├─CuredAndDeadRateChart # 治愈率和死亡率圖表 │ ├─CurrentConfirmedCompareBarChart # 最近一周累計治愈圖表 │ ├─DataMap # 數據地圖 │ └─ProvinceRankingBarChart # 累計排名圖表 ├─libs # 一些常用的配置 ├─router # 路由配置 ├─utils # 工具類 └─views # 視圖
詳細結構:
總結
采用組件化封裝各個展示圖表,能更好的圖表展示及復用;
使用 axios 請求后臺服務或本地 mock 服務獲取數據,然后重新賦值圖表中指定的數據;
項目源碼:本項目源碼已上傳至 Github,在我的博客中可查看到地址:使用Vue+DataV+Echarts打造新冠肺炎疫情數據大屏(可動態刷新)
這個項目是個人學習作品,能力有限,難免會有 BUG 和錯誤,敬請諒解。如有更好的建議或想法,請指出,謝謝
javaScript Vue
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。