Vue.js + Flask + echarts + MySQL


Description

用 Vue.js 搭建前端,使用 echarts 做數據可視化,數據從 Flask 搭建的后端提供的 API 獲取,后端用 pymysql 訪問 MySQL 獲取數據。寫一個盡可能簡單的 demo 實現這一套流程。

Solution

我們從 MySQL 中的數據開始一步步往前端搭建。為了盡可能降低耦合,我們假設,前端、后端、數據庫放在三台不同的服務器上。在本示例中,數據庫在外部服務器上,通過 SSH Tunnel 訪問;前端和后端分別運行在本機的 8080 和 5000 端口。

https://github.com/mollnn/Bilibili-Visualization

(依賴根據報錯提示安裝一下吧……懶得寫了)

數據庫查詢接口

為了偷懶,我們對數據庫訪問的過程做一些封裝,使得輸入數據庫名和查詢語句即可直接獲取結果。

該部分代碼來源於網絡。

// 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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM