[Python Flask] Vueでif文とv-model/v-on(イベント)を利用する方法

Flask
スポンサーリンク

こんにちは。

PythonのFlaskを勉強しているロペです。
今日は、FlaksでVueを利用した時のif文とv-model/v-on(イベント)を利用方法を学習したので、それを纏めて記事にしました。

誰かの役にたったら幸いです。

Vue.jsやif文の書き方の概要を書いた記事もありますので、もしよければ覗いてみてください。

FlaskのVue.jsの概要記事

FlaskのVue.jsでif文を書く概要

スポンサーリンク

if文を使用してやりたいこと

最初にif文を利用してやりたいことを書きます。

まずは、以下のようにユーザーに文字の記入を要求します。

Hello worldと書いて、Clickボタンを押したとき、
“あなたが書いた文字:Hello World”
と表示できるようにします。

もし、空白の状況でClickのボタンを押したときは
“空白でしたので何か書いてください:”
と表示するようにします。

これを、if文,V-model,v-onを利用して実行できようにします。

コードと解説

では、実際に書いたコードで大事な部分の抜粋を紹介します。
(Flaskのスクリプトを含んだコードの全文は一番下に書いておきます)

HTMLのコード

このコードで上記の図の遷移を実行しています。

{% raw %}
<script type="text/x-template" id="mycomp-template">
    <div>
        <div v-if="msg ==''"
        class="' h5 alert alert-light">
        {{alert}}
        </div> 
        <div v-else 
        class="' h5 alert alert-primary">
        {{alert}}
        </div>
        <div class="form-group">
            <label for="msg">Message</label>
            <input type="text" class="form-control col"
            id="msg" v-model="msg">
            <button v-on:click="action" class="col-2" style="height:80%; font-size:80%">
                Click</button>
        </div>
    </div>
</script>
{% endraw %}

<script>
// mycomp object
// mycomp object


Vue.component('mycomp',{
    template:'#mycomp-template',
    data: function(){
        return{
            flg:false,
            msg:'',
            alert:'何か書いてください:'
         };
    },
    methods:{
        action:function(e){
            if (this.msg==''){
                this.alert = '空白でしたので何か書いてください:';
                this.flg = false;
            }else{
                this.alert='あなたが書いた文字: ' + this.msg;
                this.flg = true;
            }
        }
    }
});

解説

まず最初に、v-modelについて説明しておきます。

V-modelによる値管理

Vue.jsでは、「v-model」という値を管理するために専用のディレクティブが用意されており、これを利用することで簡単に入力値を利用できます。
なお、v-modelは以下で記述することができます。

v-model=”変数名”

上記のコードでは、このv-modelを利用してMessageボックス内に記述した文字列を

”msg”

と定義しています。

if文

{% raw %} {% endraw %}
間に画面に出力する文字列をalertに定義して、idを変数にif文で書いています。
(これによって、msgの値は入力に合わせて自動に更新されます)

さらに、上記のv-modelで定義したmsgの値によって、if文による条件分岐しています。
(つまり、msgは自動に更新されるため、表示されるメッセージも常に書き換わります)

なお、変数alertの文字列は、methods:{}の間のコードで記述しています。

v-on(イベント)

Vue.jsのコンポーネントでイベントを利用する場合、「v-on」というディレクティブを使用します(これは、イベントと、コンポーネントに用意されているメソッドを関連付けるものになります)
このv-onで、メソッド名を指定して関連づけることで、コンポーネントに用意されているメソッドが呼び出されるようになります。

使用方法は

v-on:イベント名=”メソッド名”

になります。

コンポーネント側では、「methods」という値を使ってメソッドを用意しており、以下のような方に記述できます。

methods:{
メソッド名:function(e){*
*},
}

methodsの値には、メソッド名と実行する関数をオブジェクトにまとめたものを指定する必要があります。これで、指定したメソッド名をv-onの値に指定すれば良いのです。

参考:コードの全文

今回、試しに作成したサンプルコードの全文も載せておきます。

Flaskのサンプルコード

from flask import Flask, render_template, request, session, url_for, redirect
from flask.views import MethodView
import random

app = Flask(__name__)
@app.route('/', methods=['GET'])
def index5():
    return render_template('index4.html',\
        title='Vue.js',\
        message='This is sample of v-model and v-on',
       )

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

HTMLのコード

{% extends "layout2.html" %}
{% block title %}
index3
{% endblock %}

{% block headline %}
{{title}}
{% endblock %}

{% block content %}
<div class="mb-3" id="msg">{{message}}</div>

<div id="app" class="m-5">
    <mycomp n/>
</div>

{% raw %}
<script type="text/x-template" id="mycomp-template">
    <div>
        <div v-if="msg ==''"
        class="' h5 alert alert-light">
        {{alert}}
        </div> 
        <div v-else 
        class="' h5 alert alert-primary">
        {{alert}}
        </div>
        <div class="form-group">
            <label for="msg">Message</label>
            <input type="text" class="form-control col"
            id="msg" v-model="msg">
            <button v-on:click="action" class="col-2" style="height:80%; font-size:80%">
                Click</button>
        </div>
    </div>
</script>
{% endraw %}

<script>
// mycomp object
// mycomp object


Vue.component('mycomp',{
    template:'#mycomp-template',
    data: function(){
        return{
            flg:false,
            msg:'',
            alert:'何か書いてください:'
         };
    },
    methods:{
        action:function(e){
            if (this.msg==''){
                this.alert = '空白でしたので何か書いてください:';
                this.flg = false;
            }else{
                this.alert='あなたが書いた文字: ' + this.msg;
                this.flg = true;
            }
        }
    }
});

// start Vue.
new Vue({
    el:'#app',
})
</script>
{% endblock %}
{% block footer %}
Coryright 2020 Rope_blog
{% endblock %}

HTMLのコード(layout)

<!doctype html>
<html lang="ja">
<head>
    <title>{%block title %}{% endblock %}</title>
    <meta charset="utf-8"/>
    <meta name="vieport"
        content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="stylesheet" href="{{url_for('static',filename='style.css')}}">
            <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
            <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" ></script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
            <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    </script> 
</head>
<body>
    <div class="test" style="background-color:rgb(222, 243, 234);">
        <div class="target">
            <div class="container" style="max-width: 100%;">
                <div style="display: table;width:100%;">
                    <div style="display:table-cell; vertical-align:middle;font-size: 30px;">
                        <div class="text-left" style="border-bottom:5px solid rgb(135, 250, 196);" >
                        <h1 class="display-3">
                            <div style="font-size: 50px;">
                            {% block headline %}{% endblock %}
                            </div>
                        </h1>
                        </div>
                        <div style="border-bottom:5px solid rgb(135, 250, 196);" >
                            {% block content %}{% endblock %}
                        </div>

                        <div class="text-right">
                        {% block footer %}{% endblock %}
                        </div>
                    </div>
                </div>
            </div>
        </div>   
    </div>
</body>
</html>

以上になります。

コメント

タイトルとURLをコピーしました