Vue.js+Flaskで画面描画しようとしたら失敗した話

前回記事の続きです。

Vueをbuildし、FlaskからVue側のファイルを参照できるようになりましたがどちらも初期セットアップ状態なので中身を以下のように変えて表示できるか試してみようと思います。

  • Flask側ではmysqlに接続して任意テーブルへSELECTを実行

  • Vue側ではSELECT結果をFlaskから受け取って画面表示

結論

今回実施した内容ではFlaskからVueに値を渡すことが出来ませんでしたので自己学習の一環として実施結果を残します。

バックエンド側

まずはDBの準備です。FlaskからSQLを実行する際にはsqlite+SQLAlchemyがよく取り上げられていますが、今回はmysqlを使って試してみます。Pythonからmysqlに接続するにはmysql-connector-pythonをインストールする必要があるため事前にpipで取得しておきます。

pip install mysql-connector-python

テーブルは以下テーブルを作成してテストデータを投入しました。

CREATE TABLE kakeibo (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255),
    price DECIMAL(10, 2),
    purchase_date DATE
);

INSERT INTO kakeibo (title, price, purchase_date) 
VALUES 
('iPhone 12', 130000, '20240404'),
('Samsung Galaxy S21', 90000, '20240403'),
('PlayStation 5', 50000, '20240402');

DB準備が完了したら前回作成したapp.pyファイルに以下の記述を追記していきます。pipで取得したmysql-connector-pythonを用いてqueryExecというメソッドを新規追加し、indexメソッド内から呼び出しています。取得した結果はrender_templateで画面へ渡すようにしました。

import mysql.connector

def queryExec(query):
    conn = mysql.connector.connect(
        host = 'localhost',
        user = 'root',
        passwd = 'pass',
        db = 'fla'
    )
    cursor = conn.cursor()
    cursor.execute(query)
    result = cursor.fetchall()
    cursor.close()
    conn.close()
    print(result)
    return result

@app.route('/')
def index():
    result = queryExec("SELECT * FROM kakeibo")
    if result is None:
        result = []
    return render_template('index.html',result = result)

====== その他箇所は前回と同一ソース ======

フロントエンド側

Vue側については初期状態でいろんな文言が表示されているので一旦全て削除し、Flaskから渡された値のみを表示するように変えてみます。

  • index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
  • App.vue

<script setup>
import PieChart from './components/PieChart.vue'
</script>

<template>
  <header>
  </header>

  <main>
    <PieChart />
  </main>
</template>

<style scoped>

</style>
  • PieChart.vue

<script setup>

</script>
<template>
    <div>{{ result }}</div>
</template>

作りとしてはindex.html内でApp.vueを参照し、さらにその中からPieChart.vueを参照。PieChart.vue内にある{{ result }}にSQLの結果リストが表示されるのではないか?と思い実行してみました。

結果

画面上には何も表示されませんでした。
それもそのはずで、Vue側を一度buildした時点でApp.vueやPieChart.vueはjsとしてbuild結果に反映されるためFlaskで渡したresultはどこにも表示されないのです。FlaskのqueryExecメソッド内ではSELECT結果をprintしているため、SELECTの結果自体は問題なさそうなので別の方法でFlaskの結果を参照する必要があるようでした。
類似記事を見てみるとAxiosなどを使ってvueの中から直接Flask処理を実行し、そのレスポンスをVue内で解釈して画面に反映する方法があるようなので次回はそれを試してみたいと思います。

この記事が気に入ったらサポートをしてみませんか?