Vue.jsをFlaskで動かす
Vue.jsをFlaskで動かしたい
VueとFlaskの連携について説明します.flask_restfulを用いて簡単な通信もやります.
Vueのプロジェクトを作る
vue init webpack test
いろいろ聞かれますが,だいたいEnterで大丈夫です.ESLintだけは使い方がよくわかってないのでNoにしてます.
まってるとめっちゃインストーーーーーーーールって感じになるので放置です.結構長い時間がかかるかも
インストールが終わったら以下のコマンドでプロジェクトに入っておいてください
cd test
あとで使うのでインストールしておくといいかも・・・
npm install axios --save npm install url-join --save
Flaskをインストール
先ほどtestディレクトリに入ったのでそのまま
mkdir env python3 -m venv env source env/bin/activate pip3 install flask flask_cors flask_restful
これでとりあえずFlaskを使える環境は整いました
Flaskでサーバーを立てる
次にFlaskでwebサーバーを立てます
そのまえにVueのプロジェクトをビルドして・・・・
npm run build
ビルドしている間にバックエンドの方やっちゃいましょう!
ファイル名はserver.pyで
配置する場所はプロジェクトフォルダ直下(index.htmlとか.gitignoreある場所)
from flask import Flask, jsonify, render_template from flask_cors import CORS from flask_restful import Api, Resource, reqparse app = Flask(__name__, static_folder="dist/static", template_folder="dist") CORS(app) api = Api(app) #get, post, put, deleteリクエストがあったときの処理をそれぞれ書く class test(Resource): parser = reqparse.RequestParser() # add_argumentでパラメータを取得できます # この辺はflask_restfulの公式ドキュメントに色々乗ってるのでそっち見た方がよさげ parser.add_argument("message") def get(self): args = self.parser.parse_args() return {"message": args["message"]} def post(self): args = self.parser.parse_args() return {"message": args["message"]} def put(self): args = self.parser.parse_args() return {"message": args["message"]} def delete(self): args = self.parser.parse_args() return {"message": args["message"]} api.add_resource(test, "/api/test") @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def get_vue(path): return render_template('index.html') # 一応エラーハンドラ @app.errorhandler(403) @app.errorhandler(404) @app.errorhandler(500) def error_handler(error): msg = 'Error: {code}'.format(code=error.code) return jsonify({"result": "Failed", "message": msg, "errorcode": error.code}) if __name__ == "__main__": app.run(host='0.0.0.0', debug=True)
python3 server.py
これでlocalhost:5000につないだときにVueの画面が出てこれば成功です
server.jsも全く同じことしてるんだから早めに気づけばよかった・・・って思ってます
API叩きたくない?叩きたいよね
先ほど作ったserver.pyにAPIが生えているのでちょっと通信してみましょう
いちいちビルド(npm run build)していると面倒なので開発版でもserver.pyに接続できるようにします.
と言っても,npm run devで立つサーバーとserver.pyで立てるサーバで2つあるからserver.pyの方に誘導してあげるだけですが・・・・
APIと通信するモジュール(myAxios.js)
import axios from 'axios' const urljoin = require('url-join'); const debug = process.env.NODE_ENV != 'production' const debug_url = "http://localhost:5000" const onSuccess = (res) => { if (debug) console.log(' << ' + JSON.stringify(res.data)) return Promise.resolve(res) } const onError = (res) => { console.log(res) throw new Error('API error') } const accessUrl = (endpoint) => { if (debug) return urljoin(debug_url, endpoint) else return endpoint } const debugMessage = (type, url, params) => { console.log(type + ": " + url + '\nparams: ' + JSON.stringify(params)) } export default { get: (url, params) => { let reqUrl = accessUrl(url) if (debug) debugMessage("GET", reqUrl, params) return axios.get(reqUrl, { params }).then(onSuccess).catch(onError) }, post: (url, params) => { let reqUrl = accessUrl(url) if (debug) debugMessage("POST", reqUrl, params) return axios.post(reqUrl, params).then(onSuccess).catch(onError) }, put: (url, params) => { let reqUrl = accessUrl(url) if (debug) debugMessage("PUT", reqUrl, params) return axios.put(reqUrl, params).then(onSuccess).catch(onError) }, delete: (url, params) => { let reqUrl = accessUrl(url) if (debug) debugMessage("DELTE", reqUrl, params) return axios.delete(reqUrl, { data: params }).then(onSuccess).catch(onError) } }
const debug_url = "http://localhost:5000"
となっているのはserver.pyがポート5000で立つからです.server.pyの立つポート別の時はそれを指定してあげてください
test.vueをcomponentsの中に作ってください.内容はこんな感じ
<template> <h1> {{get}} {{post}} {{put}} {{del}} </h1> </template> <script> import myAxios from "./myAxios.js"; export default { name: "ApiTest", data() { return { get: "", post: "", put: "", del: "" }; }, created() { myAxios.get("api/test", { message: "Hello" }).then(res => { this.get = res.data.message; }); myAxios.post("api/test", { message: "World" }).then(res => { this.post = res.data.message; }); myAxios.put("api/test", { message: "Vueと" }).then(res => { this.put = res.data.message; }); myAxios.delete("api/test", { message: "Flaskの連携" }).then(res => { this.del = res.data.message; }); } }; </script>
このままだとHelloWorld.vueしか表示されないのでちょっと変えます.
router/index.jsを以下のように変更
import Vue from 'vue' import Router from 'vue-router' import test from '@/components/test' Vue.use(Router) export default new Router({ mode: 'history', routes: [{ path: '/', name: 'Test', component: test }] })
npm run devしてhttp://localhost:8080に接続すると・・・ できましたね!
もちろん
npm run build
をしてhttp://localhost:5000に接続しても同じ画面になると思います.
終わりに
FlaskとVueの連携を説明してみました. めっちゃむずかしそーって思ってたんですけど案外簡単ですね!これでめんどくさそうなDB処理はPythonでかけそうです
というかVueRouterでルーティングした時Flaskでルーティングしたところあけなきゃいけないのかなぁ・・・・まだまだわからないところがあるので実験して分かったらまた記事を書きます〜
そろそろPyTrochとかの記事書きたいんだけど,如何せんチュートリアルに書いてある以上のことがまだできてない・・・・チュートリアルがある程度理解できたらなにか書くかもしれません
多分MQTTサーバーをFlaskで作ったよ〜って記事が先になると思います
こんな感じで今回は終わりにします.ありがとうございました
よかったらフォローしてね〜