概要
Flaskで作成したAPIとVue.jsで通信して画面を表示するページを作成するローカル環境を作る。
バージョン情報
- flask==1.1.1
- Flask-Cors==3.0.9
Flask-RESTful==0.3.8
"vue": "^2.6.11"
- "vue-router": "^3.4.8"
- "axios": "^0.21.0"
- @vue/cli 4.5.7
Flaskのアプリの生成
事前にFlaskのAPIを作っておく。
アプリの内容は簡単にxというパラメータを受けたらそれを2倍にして返すというもの。
requirements.txt の内容は下記あたり。
flask==1.1.1 Flask-Cors==3.0.9 Flask-RESTful==0.3.8
app.py
import random from flask import Flask, request from flask_restful import Api, Resource, fields, marshal_with from flask_cors import CORS app = Flask(__name__) CORS(app) api = Api(app) resource_fields = { 'value': fields.Float } class TwoTimesValue(object): def __init__(self, value): self.value = value * 2 class TwoTimes(Resource): @marshal_with(resource_fields) def post(self): json_data = request.get_json(force=True) app.logger.info(json_data) return TwoTimesValue(json_data['param']) api.add_resource(TwoTimes, '/') if __name__ == '__main__': app.run(host='0.0.0.0', debug=True)
起動
$ python app.py
curlで動作確認
$ curl --header "Content-Type: application/json" \ --request GET \ --data '{"param":2}' \ http://localhost:5000/
結果
{ "value": 4.0 }
これで数値を2倍するAPIが作れた。
APIを呼んで結果を表示するVue.jsアプリ
vue-cliからプロジェクトの生成。
$ vue create axios-example $ cd axios-example
API通信用にaxiosとansi-regexを入れておく。あとvue-routerも。
$ yarn add axios ansi-regex vue-router
今回はクエリストリングの値からAPIを呼び出す版と、フォームの入力値から呼び出す版の2つを用意してみる。
main.js
import Vue from 'vue' import App from './App.vue' import router from './router' new Vue({ render: h => h(App), router, }).$mount('#app')
router.js。 / の場合はクエリストリングから、/form_version の場合はformの内容から取るコンポーネントを呼ぶ。
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes = [ { path: '/', component: () => import("./components/QueryVersion"), props: (route) => ({ param: Number.parseInt(route.query.param, 0) }) }, { path: '/form_version', component: () => import("./components/FormVersion"), }, ] export default new VueRouter({ mode: 'history', routes, })
app.vue。router-viewとrouter-linkを定義。router-linkではparamに3を入れてクエリ文字列を送る。
<template> <div id="app"> <router-view></router-view> <ul> <li> <router-link v-bind:to="{path: '/', query: {param: 3}}">query version</router-link> </li> <li> <router-link to="/form_version">form version</router-link> </li> </ul> </div> </template> <script> export default { name: 'App', } </script>
./components/QueryVersion.vue。クエリ版の記述。Routerからクエリ文字列がparamに入れられるので、それを利用してaxiosでlocalhost:5000へパラメータを送る。
<template> <div id="query-version"> {{ param }} * 2 = {{ value }} </div> </template> <script> import axios from 'axios' axios.defaults.baseURL = 'http://localhost:5000'; export default { name: 'query-version', data: function() { return { value: 0 } }, props: { param: Number, }, mounted: function() { this.updateValue() }, watch: { param: function() { this.updateValue() }, }, methods: { updateValue: function() { const vm = this; axios.post("/", { 'param': vm.param }, { headers: { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application / x-www-form-urlencoded', } } ).then(function(response){ vm.value = response.data.value } ); } } } </script>
mountedでまずAPIを呼び出す。またparamをwatchしておいて変更された場合にも呼び出す。
これで http://localhost:8080/?param=4 を呼び出すと4でAPIが呼ばれて8が返り、その値が画面に表示される。
続いてフォーム版。
components/FormVersion.vue
<template> <div id="form-version"> <p><input v-model="param" placeholder="input number"></p> <p>{{ param }} * 2 = {{ value }}</p> </div> </template> <script> import axios from 'axios' axios.defaults.baseURL = 'http://localhost:5000'; export default { name: 'form-version', data: function() { return { 'param': null, 'value': null, } }, watch: { param: function(newParam) { this.updateValue(newParam) }, }, methods: { updateValue: function(param) { const vm = this; axios.post("/", { 'param': Number(param) }, { headers: { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application / x-www-form-urlencoded', } } ).then(function(response){ vm.value = response.data.value } ); } } } </script>
paramの内容をwatchして変更があればAPIを呼ぶ。
これでフォームに入力があるたびにAPIが呼ばれて画面に値が出力される。
改定履歴
Author: Masato Watanabe, Date: 2020-11-03, 記事投稿