kivantium活動日記

プログラムを使っていろいろやります

Vue.jsとFlaskの間でフォーム情報をやり取りする

Pythonで作ったプログラムにWebインターフェースをつけることができると便利です。
せっかくなのでフロントエンドも勉強しようと思って見た目簡単そうなVue.jsを試しました。

ソースコード

バックエンド (Python)

PythonのシンプルなウェブアプリケーションフレームワークであるFlaskを使いました。
/にアクセスするとindex.htmlが表示されます。
/apiにPOSTでデータを送りつけると、送られたフォームデータをsplit()したものをjsonで返します。

from flask import Flask, request, render_template, jsonify
app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route("/api", methods=['POST'])
def hello():
    result = {
        "results": request.json["text"].split()
    }
    return jsonify(result)

if __name__ == '__main__':
    app.run(debug=True)

フロントエンド (Vue.js)

フロントエンドにはVue.jsを使いました。
axiosを使って/apiにフォームの情報を投げています。
検索した範囲ではVue.jsではフォーム情報をこうやって取るのが正しい雰囲気があったのですが、本当にこれが正解なのかはよく分かりません。
結果が返ってきたら結果表示欄にリストで表示します。
FlaskのレンダーとdelimiterがかぶっているのでVue.js側のdelimiterを変更する必要がありました。

<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<form v-on:submit.prevent="submit">
<textarea v-model="formData.text"></textarea>
<input type="submit" value="submit">
</form>
<div v-if="seen">
<h2>Results</h2>
<ul>
<li v-for="result in results"> [[ result ]] </li>
</ul>
</div>
</div>
</body>
<script>
const vm = new Vue({
  el: '#app',
  delimiters: ['[[', ']]'], // Flaskのdelimiterとの重複を回避
  data: {
    seen: false,
    results: [],
    formData: {
      text: ''
    }
  },
  methods: {
    submit: function() {
      axios.post('/api', this.formData)
        .then(response => {
          this.results = response.data.results;
          this.seen = true;
        })
      .catch(error => {
        console.log(error);
      })
    }
  }
});
</script>
</html>

動作例

submitする前

f:id:kivantium:20180723173258p:plain

submitした後

f:id:kivantium:20180723173339p:plain


もっと良い書き方があったら教えてください

特定商取引法に定められた事項は請求により遅滞なく提供する