[Python Flask] Vue.jsのMustacheでif文とfor文を書く方法

Flask
スポンサーリンク

PythonのFlaskでVueの書き方を勉強しているロペです。

この記事では、Vue.jsのMustache(マスタッシュ)と呼ばれるテンプレートを利用した、
if文の書き方を説明します。

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

あと、FlaskのVue導入編も書いているので、もしよければ覗いてみて欲しいです。

スポンサーリンク

導入(知っておいたほうが良いこと)

ディレクティブ

Mustacheのif文とfor文説明の前に「ディレクティブ」について知っておく必要があるかと思います。なぜなら、Mustacheの基本は「専用のディレクティブで働きを指定する」というものだからです。
ちょっと分かりにくいので、「HTMLタグに追記できる独自の属性」のようなものと考えておきましょう。

ディレクティブは、すべて名前の最初に「v-」がつきます。

つまり、HTMLのタグに「v-」と書かれていた場合、「これはディレクティブ」と考えれば良いと思います。

「v-if」:if文

「v-if」は条件をチェックして、それが成立するときだけ以下のタグを表示するものです。

書き方

<タグ v-if=”真偽値となるもの”>
trueのときの表示
</タグ>

<タグ v-else>
flaseのときの表示
</タグ>

で記述することができます。

このコードはテキストとして用意しますが、このテキストはJacaScriptの文として実行され、その結果がチェックされます。 
また、この値となるテキスト部分ではmコンポーネントのdataで用意した変数を使うことができ、この変数の値によって表示を操作できます。

v-ifは単体で使用することもできますが、「v-else」ディレクティブをつけたタグを用意することで、値がfalseのときの表示を設定することもできます。

v-ifのサンプルコード

Flaskを含めたコードの全文は下になります。

HTML

v-ifを書いた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 name="Rope" f="false"
        msg="Hello world" />
</div>



{% raw %}
<script type="text/x-template" id="mycomp-template">
    <div v-if="flg=='true'" class="alert alert-primary">
        <p class="h5">
            f="true"の結果を表示
        </p>
        <p>{{msg}}</p>
    </div>
    <div v-else class="alert alert-danger">
        <p class="h3">
            f="false"の結果を表示
</script>
{% endraw %}

<script>
// mycomp object
Vue.component('mycomp',{
    template:'#mycomp-template',
    props:['name','msg', 'f'],
    data: function(){
        return{ flg: this.f.toLowerCase() }
    }
});

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

Vueを参照しているhtml

<!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>

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-if',
        data="['One', 'Two', 'Three']")

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

実行結果

上記のサンプルコードを実行した結果は以下になります。

f=”false”と定義していてるので、

ちゃんと f=”false”の結果を表示

が出力されています。

次に、f=trueに変更にして実行してみます。

出力されると文字と背景色を変えることができました。
これでv-ifが出力されたことが確認できました。

解説

<script type="text/x-template" id="mycomp-template">
    <div v-if="flg=='true'" class="alert alert-primary">
        <p class="h5">
            f="true"の結果を表示
        </p>
        <p>{{msg}}</p>
    </div>
    <div v-else class="alert alert-danger">
        <p class="h3">
            f="false"の結果を表示
</script>
{% endraw %}

htmlのv-ifを記述して

flgがtrueの時は” f=”true”の結果を表示”
それ以外は f=”false”の結果を表示

を出力するように書いています。

<script>
// mycomp object
Vue.component('mycomp',{
    template:'#mycomp-template',
    props:['name','msg', 'f'],
    data: function(){
        return{ flg: this.f.toLowerCase() }
    }
});

ここで、returnの後に書いているthis.fというのは、props:[‘name’,’msg’,’f’]で用意しているf属性の値のことです。その値を全て小文字に変換して変数flgに設定しています。
fだけではなく、任意の好きな値に設定することができます。

これで、変数flgの値がtrueの場合とそうでない場合に、v-ifとその後ろにあるv-elseで指定したタグを表示させることができます(flgの値によって表示を切り替えることができます。)

「v-for」:for文

次にfor文について書いてきます。

書き方

<タグ v-for=”変数名 in 配列など”>

繰り返す表示

</ タグ>

で記述することができます。
v-forは、配列などのデータから順に値を取り出して表示していく、といった使い方をします。例えば、dataという配列があった場合、v-for=”item in data”と記述すれば、dataから順に値を取り出して変数itemに収めていきます。
for文を使用したい部分(繰り返し表示したい部分)では、取り出した変数itemを利用して表示するように作成します。

v-forのサンプルコード

先ほどv-ifで紹介したサンプルコードの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">
    <ul class="list-group">
        <template v-for="item in data">
            <li class="list-group-item">
                {{item.name}}[{{item.mail}},{{item.age}}]
            </li>
        </template>
    </ul>  
</script>
{% endraw %}

<script>
// mycomp object
// mycomp object
Vue.component('mycomp',{
    template:'#mycomp-template',
    props:['name','msg', 'f'],
    data: function(){
        return{
            data:[
                {name:'Rope',mail:'test@hello', age:20},
                {name:'Rope2',mail:'test2@hello', age:30},
                {name:'Rope3',mail:'test@hello', age:40}
            ]
         }
    }
});

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

実行した結果

実行してみると、

v-forで定義したname,mail,ageがリストとして、定義した通りに
繰り返されて出力されています

解説

 <template v-for="item in data">
            <li class="list-group-item">
                {{item.name}}[{{item.mail}},{{item.age}}]
            </li>
        </template>

ここでは、v-for=”item in data”で配列dataからオブジェクトをitemに取り出しています。
そして、<li>部分で、{{item.name}}というようにitemからname,mail,ageの値を取り出して表示しています。
このように必要な値をオブジェクトにまとめて配列にしておけば繰り返し処理できます。

            data:[
                {name:'Rope',mail:'test@hello', age:20},
                {name:'Rope2',mail:'test2@hello', age:30},
                {name:'Rope3',mail:'test@hello', age:40}
            ]

ここでは変数dataに配列を設定しています。
配列の中には、name,mail,ageといった項目を持つオブジェクトが保管されています。
この配列を使用して、テンプレートでリストを表示させています。

以上になります!

コメント

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