1. 程式人生 > 其它 >Vue.js + Flask + echarts + MySQL

Vue.js + Flask + echarts + MySQL

目錄

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。