LoginSignup
148
127

More than 3 years have passed since last update.

Vue.js(vue-cli)とFlaskを使って簡易アプリを作成する【後半 - サーバーサイド編】

Last updated at Posted at 2018-06-03

vueflask.png

どうもmiyachi(@_38ch)です。
前回の記事
Vue.js(vue-cli)とFlaskを使って簡易アプリを作成する【前半 - フロントエンド編】
で、フロントエンドVue.js、サーバーサイドFlaskで作る簡易SPAのフロントエンドの紹介をしました。

今回はサーバーサイド(Flask側)の作り方を書いていきます。
なお、サーバーサイドにはPython3.6を使っています。

backendディレクトリを作成

ディレクトリを切って、virtualenvで仮想環境を作ります。

$ mkdir backend
$ cd backend
$ virtualenv -p python3 venv

アクティベートします。

$ source venv/bin/activate

アクティベートが完了したら、Flaskをインストールします。

(venv) pip install Flask

ルートディレクトリ(frontend, backendと同じディレクトリ)に戻って、run.pyを作成。

(venv) cd ..
(venv) touch run.py

中身はこんな感じ

from flask import Flask, render_template
app = Flask(__name__,
            static_folder = "./dist/static",
            template_folder = "./dist")
@app.route('/')
def index():
    return render_template("index.html")

このrun.pyは一般的なFlask starterとは少し異なります。
どこが違うかというと、static_folderとtemplate_folderの部分。
templateファイルはfrontendから生成されたものを読み込む必要があるので、ここでパスを指定しています。

Flaskサーバーを起動

以下を実行してあげると、Flaskサーバーが立ち上がります。

(venv) FLASK_APP=run.py FLASK_DEBUG=1 flask run

localhost:5000で確認できます。
最初のページはうまく表示されますが、/aboutに行くとNOT FOUNDになってしまいました。

image.png

run.pyの設定を少し変えてあげましょう。

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
    return render_template("index.html")

これで正常にaboutページが表示されるはず。

APIエンドポイントを追加

1-100でランダムな数値を返すシンプルなAPIを作成します。
run.pyを以下のように修正します。

from flask import Flask, render_template, jsonify
from random import *
app = Flask(__name__,
            static_folder = "./dist/static",
            template_folder = "./dist")

@app.route('/api/random')
def random_number():
    response = {
        'randomNumber': randint(1, 100)
    }
    return jsonify(response)

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
    return render_template("index.html")

'/api/random'にリクエストを投げるとランダムな数値を以下のようなJSON形式で返してくれる。

{
  "randomNumber": 36
}

ブラウザで localhost:5000/api/random にアクセスしてテストできます。
image.png

サーバーサイドで動作が確認できたら、それをフロントから呼べるようにしましょう。
Home.vueを以下のように修正します。

Home.vue
<template>
  <div>
    <p>Home page</p>
    <p>Random number from backend: {{ randomNumber }}</p>
    <button @click="getRandom">New random number</button>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  data () {
    return {
      randomNumber: 0
    }
  },
  methods: {
    getRandom () {
      this.randomNumber = this.getRandomFromBackend()
    },
    getRandomFromBackend () {
      const path = `http://localhost:5000/api/random`
      axios.get(path)
      .then(response => {
        this.randomNumber = response.data.randomNumber
      })
      .catch(error => {
        console.log(error)
      })
  }
},
  created () {
    this.getRandom()
  }
}
</script>

大まかに説明すると、

  • randomNumberは0で初期化されている。
  • ボタンをクリックすると、getRandomが走る。
  • getRandomが走ると、サーバーサイドにHTTPリクエストが送られ、ランダムな数値が返ってくる。
  • randomNumberが更新されて、画面の値が変わる

という感じです。

backendにHTTPリクエストをなげるためには、axiosというライブラリを使用します。

(venv) cd frontend
(venv) npm install --save axios

フロントを更新したので、再度 npm run build を実行して、
localhost:5000から確認します。

Jun-03-2018 1-02-26 PM.gif

正常にランダムな数値を取得するAPIを実装できました。
間違え、ご指摘などあれば、コメント欄にいただけると助かります。

ソースコード

今回使用したコードはこちらにあげておきます。
もしお役にたったらStarいただけると嬉しいです。
https://github.com/miyachin/vue-flask-sample

148
127
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
148
127