シェルスクリプトマガジン

作りながら学ぶVue.js入門(Vol.97掲載)

著者:大津 真

JavaScriptフレームワークの中でも、学びやすさと柔軟さで人気を集めている「Vue.js」。本連載では、Vue.jsの基礎から実践的な使い方までを、分かりやすく丁寧に解説していきます。一緒にフロントエンド開発の楽しさを体験してみましょう。第2回では、テンプレート構文において、各要素に特別な動作を与えるための機能であるディレクティブの基礎について説明します。

シェルスクリプトマガジン Vol.97は以下のリンク先でご購入できます。

図1 オブジェクトリテラルの例

{
    name: name,
    age: age,
    scores: { math: [40, 50], eng: [70, 60] },  
    sayHello: function() {
        console.log('こんにちは');
    }
}

図2 シンプルなVueアプリ「sample1.html」の主要部分のコード

<script type="module">
    import { createApp, ref } from 'vue'
    createApp({
        setup() {
        const msg = ref('ハローVue')
            const person = ref({name:'大津真', age: 35})
            return {
                msg, person
            }
        }
    }).mount('#app')
</script>
<div id="app">
    <h1>{{ msg }}</h1>
    <p>{{ person  }}</p>
</div>

図3 ボタンクリックで値を増減させるVueアプリ「counter1.html」のコード(抜粋)

<script type="module">
    import { createApp, ref } from 'vue'
    createApp({
        setup() {
            // counterをリアクティブな変数として定義
            const counter = ref(0) 
            // counterを「1」増やす
            function increment() {  
                counter.value++
            }
            // counterを「1」減らす
            function decrement() {
                counter.value--
            }
            return {
                counter,
                increment,
                decrement   
            }
        }
    }).mount('#app')
</script>
<div id="app">
    <h1>カウント: {{ counter }}</h1>
    <button v-on:click="increment">+</button>
    <button v-on:click="decrement">-</button>
</div>

図4 図3のアプリをインラインイベントハンドラを用いて書き換えた「counter2.html」のコード(抜粋)

<script type="module">
    import { createApp, ref } from 'vue'
    createApp({
        setup() {
            // counterをリアクティブな変数として定義
            const counter = ref(0)
            return {
                counter,
            }
        }
    }).mount('#app')
</script>
<div id="app">
    <h1>カウント: {{ counter }}</h1>
    <button @click="counter += 1">+</button>
    <button @click="counter -= 1">-</button>
</div>

図5 図4のアプリに「3倍にする」ボタンを追加した「counter3.html」のコード(抜粋)

<script type="module">
    import { createApp, ref } from 'vue'
    createApp({
        setup() {
            // counterをリアクティブな変数として定義
            const counter = ref(0)
            const multiplier = ref(3)
            // counterをn倍にする
            function multiply(n) {
                counter.value *= n
             }
            return {
                counter,
                multiply,
                multiplier
            }
        }
    }).mount('#app')
</script>
<div id="app">
    <h1>カウント: {{ counter }}</h1>
    <button @click="counter += 1">+</button>
    <button @click="counter -= 1">-</button>
    <button @click="multiply(multiplier)">
        {{ multiplier }}倍にする</button>
</div>

図6 マスタッシュ構文とv-htmlの違いを示す「v-html1.html」のコード(抜粋)

<script type="module">
    import { createApp } from 'vue'
    createApp({
        setup() {
            const msg1 = 'msg1:\
                          <span style="font-size:3em;color: red;">\
                          ハローVue</span>'
            return { msg1 }
        }
    }).mount('#app')
</script>
<div id="app">
    <p>{{ msg1 }}</p>
    <p v-html="msg1"></p>
</div>

図9 おみくじアプリ「omikuji1.html」のコード(抜粋)

<script type="module">
    import { createApp, ref } from 'vue'
    createApp({
        setup() {
            // おみくじの画像ファイル名を配列で定義
            const kujis = ["daikichi.png", "chukichi.png", "syokichi.png", "kyo.png"]
            // 初期画像を設定
            const kuji = ref('default.png')
            // おみくじを引く関数
            function changeKuji() {
                const randomIndex = Math.floor(Math.random() * kujis.length)
                kuji.value = kujis[randomIndex] 
            }
            return {
                kuji,
                changeKuji
            }
        }
    }).mount('#app')
</script>
<div id="app">
    <h1>おみくじ</h1>
    <div>
        <button @click="changeKuji">おみくじを引く</button>
    </div>
    <img :src="'figs/' + kuji" alt="おみくじ" @click="changeKuji">
</div>

図11 「style1.html」のコード(抜粋)

<script type="module">
    import { createApp, ref } from 'vue'
    createApp({
        setup() {
            const fcolor = 'red'
            const size   = '4em'
            const align  = ref('left')
            function setAlign(value) {
                align.value = value
            }
            return {
                fcolor, align, size, setAlign           
            }
        }
    }).mount('#app')
</script>
<div id="app">
    <div>
        <button @click="setAlign('left')">左寄せ</button>
        <button @click="setAlign('center')">中央寄せ</button>
        <button @click="setAlign('right')">右寄せ</button>
        <p :style="{color:fcolor, textAlign:align, fontSize:size}">Vue.js</p>
    </div>
</div>

図12 「style2.html」のコード(抜粋)

<script type="module">
    import { createApp, ref } from 'vue'
    createApp({
        setup() {
            const styleAll = ref({
                color:    'red'
                fontSize: '4em'
                textAlign: 'left'
            })
            function setAlign(value) {
                styleALL.value.textAlign = value
            }
            return {
                styleAll, setAlign           
            }
        }
    }).mount('#app')
</script>
<div id="app">
    <div>
        <button @click="setAlign('left')">左寄せ</button>
        <button @click="setAlign('center')">中央寄せ</button>
        <button @click="setAlign('right')">右寄せ</button>
        <p :style="styleAll">Vue.js</p>   ←③
    </div>
</div>

図13 「style3.html」のコード(抜粋)

<script type="module">
    import { createApp, ref } from 'vue'
    createApp({
        setup() {
            const styleAll = ref({
                color:    'red'
                fontSize: '4em'
                textAlign: 'left'
            })
            const styleAdd = ref({
                color: 'blue',
                backgroundColor: 'yellow',
            })
(略)
            return {
                styleAll, styleAdd, setAlign           
            }        }
    }).mount('#app')
</script>
<div id="app">
    <div>
 (略)
        <p :style="[styleAll, styleAdd]">Vue.js</p>
    </div>
</div>

図17 「class1.html」のコード(抜粋)

<style>
    .class1 {
        text-align: center;
        color: blue;
    }
    .class2 {
        font-size: 4em;
        color: red;
    }
</style>
(略)
<script type="module">
    import { createApp, ref } from 'vue'
    createApp({
        setup() {
            const enableClass2 = ref(false)
            return {
                enableClass2
            }
        }
    }).mount('#app')
</script>
<div id="app">
    <button @click="enableClass2=!enableClass2">class2を有効/無効</button>
    <p :class="{class1:true, class2:enableClass2}">Vue.jsの世界</p>
</div>