Vue.js + Flask + echarts + MySQL
阿新 • • 發佈:2021-07-12
目錄
Description
用 Vue.js 搭建前端,使用 echarts 做資料視覺化,資料從 Flask 搭建的後端提供的 API 獲取,後端用 pymysql 訪問 MySQL 獲取資料。寫一個儘可能簡單的 demo 實現這一套流程。
Solution
我們從 MySQL 中的資料開始一步步往前端搭建。為了儘可能降低耦合,我們假設,前端、後端、資料庫放在三臺不同的伺服器上。在本示例中,資料庫在外部伺服器上,通過 SSH Tunnel 訪問;前端和後端分別執行在本機的 8080 和 5000 埠。
資料庫查詢介面
為了偷懶,我們對資料庫訪問的過程做一些封裝,使得輸入資料庫名和查詢語句即可直接獲取結果。
該部分程式碼來源於網路。
// connectorSSHMySQL.py import pymysql from sshtunnel import SSHTunnelForwarder def SSHMysql(DB, SQL): server = SSHTunnelForwarder( ssh_address_or_host=('?.?.com', 22), # 指定ssh登入的跳轉機的address ssh_username='?', # 跳轉機的使用者 ssh_password='?', # 跳轉機的密碼 local_bind_address=('127.0.0.1', 1268), # 對映到本機的地址和埠 remote_bind_address=('localhost', 3306)) # 資料庫的地址和埠 server.start() # 啟用SSH db = pymysql.connect( host="127.0.0.1", # 對映地址local_bind_address IP port=1268, # 對映地址local_bind_address埠 user="root", passwd="?", database=DB, charset='utf8') cursor = db.cursor() cursor.execute(SQL.encode('utf8')) data = cursor.fetchall() cursor.close() return data def query(DB, SQL): return SSHMysql(DB, SQL) if __name__ == "__main__": SQL = "SELECT * FROM Danmu;" SelectResult = SSHMysql('bilibili', SQL) print(SelectResult)
Flask 後端
後端的任務主要是返回 JSON 格式的資料。這裡沒有引入帶引數的查詢。提供了兩個 API 介面,一個從資料庫中拉取,一個直接硬編碼資料。用於不同情況的測試。
// app.py from flask import Flask, jsonify, render_template from flask.helpers import make_response import connectorSSHMySQL as msql from flask_cors import CORS app = Flask(__name__) CORS(app, resources=r'/*') @app.route('/api/demo/') def api_demo(): return jsonify(msql.query("bilibili", "select view, danmaku from Vinfo;")) @app.route('/api/test/') def api_test(): ans = jsonify({ "product": [5, 20, 36, 10, 10, 20] }) return make_response(ans) if __name__ == '__main__': app.run(debug=True)
echarts 圖表元件
建立元件,其名為 chart1
,從官網上抄個 option,加上從後端介面拉資料的 vue-resource 操作。注意 get 路徑一定要加 http://
,同時儘量設定一下 header,畢竟是跨域請求。
// chart1.vue
<template>
<div>
<div id="echartContainer" style="width: 100%; height: 500px"></div>
</div>
</template>
<script>
export default {
name: "chart1",
data() {
return {};
},
methods: {
draw() {
var myChart = this.$echarts.init(
document.getElementById("echartContainer"),
"infographic"
);
myChart.setOption({
xAxis: {},
yAxis: {},
series: [
{
symbolSize: 5,
data: [],
type: "scatter",
},
],
});
this.$http
.get("http://localhost:5000/api/demo/", {
headers: { "Access-Control-Allow-Origin": "*" },
})
.then((res) => {
myChart.hideLoading();
myChart.setOption({ series: [{ data: res.data }] });
});
},
},
mounted() {
this.draw();
},
};
</script>
<style></style>
Vue.js 前端
把各種東西在 main.js
中引入一下,並在 app
中註冊和建立一個 chart1
。
// main.js
import Vue from 'vue'
import App from './App.vue'
import VueResource from 'vue-resource'
import * as VueJsonp from 'vue-jsonp'
import echarts from 'echarts'
Vue.use(VueJsonp)
Vue.use(VueResource)
Vue.prototype.$echarts = echarts
new Vue({
el: '#app',
render: h => h(App)
})
// App.vue
<template>
<div class="main">
<chart1 />
</div>
</template>
<script>
import chart1 from "./components/chart1.vue";
export default {
components: {
chart1,
},
};
</script>
專案結構
測試
在後端根目錄下
python app.py
在前端根目錄下
npm run dev
瀏覽器訪問 localhost:8080
,看到這麼個圖
這反映的是 B 站部分視訊的彈幕數量和播放量的關係。
魔改指南
後端加 API 直接添路由改 SQL 即可。
前端加圖,從 echarts 官網拿 option 改改,把 option 的 JSON 直接貼到 myChart.setOption(...)
中,修改 this.$http.get("...",...)...
中 GET 的 URL。