Vue.jsを使ってみよう その3


目次

こんばんは、フリューのジョンです。Vue.jsを社内に広める活動を頑張ってます。

前回はVue.jsの基本の話、elプロパティ、dataプロパティ、methodsプロパティの話をしました。

今回はVue.jsのHTML側(v-bind、v-model、v-on)の話をしていきたいと思います。

今回もVue.jsはバージョン2.3.0を使用します。

v-bindやv-onなどの属性を、Vue.jsでは、それぞれを「ディレクティブ」と呼んでいます。

v-bindディレクティブ

タグ要素のattributeにdataプロパティやmethodsプロパティの結果を当てはめる(バインドする)事ができます。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-bindディレクティブについて1</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.min.js"></script>
    <script>
    window.onload = () => {
      new Vue({
        data: () => {
          return {
            url: 'http://tech.furyu.jp/blog/wp-content/themes/furyu/logo_furyu.png',
            width: 200
          }
        },
        el: '#vue'
      });
    }
    </script>
</head>
<body>
<section id="vue">
  <img v-bind:src="url" v-bind:width="width"> <!-- {{url}} などのように記述しないことに注意してください -->
  <img :src="url" :width="width"> <!-- v-bind: は省略して : にすることができます -->
</section>
</body>
</html>

classやstyleの属性については、少し特殊な書き方で値をバインドすることができます。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-bindディレクティブについて2</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.min.js"></script>
    <script>
    window.onload = () => {
      new Vue({
        data: () => {
          return {
            clazz: {
              red: true,
              blue: false
            }
          }
        },
        el: '#vue'
      });
    }
    </script>
    <style>
      .red {
        color: red;
      }
      .blue {
        color: blue;
      }
    </style>
</head>
<body>
<section id="vue">
  <p :class="clazz">赤い文字</p> <!--trueになっているプロパティがclassにセットされる-->
  <p :class="clazz.blue === false ? 'blue' : ''">無理やり青い文字</p>
</section>
</body>
</html>

v-modelディレクティブ

v-bindでは属性値に値を入れることができましたが、v-bindでは入れるだけではなく、監視して更新することができます。

更新が走る属性値、つまり、inputやtextareaタグのvalue属性につけることでその値を監視することができます。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-bindディレクティブについて1</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.js"></script>
    <script>
    window.onload = () => {
      new Vue({
        data: () => {
          return {
            name: 'john'
          }
        },
        el: '#vue'
      });
    }
    </script>
</head>
<body>
<section id="vue">
  <input v-model="name" /> <!--inputの中身を変更するとnameの値が変化する-->
  <span>{{name}}</span>
</section>
</body>
</html>

selectに対しても記述することができます。この際、初期値のvalueがselectedになることを覚えておきましょう。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-bindディレクティブについて2</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.js"></script>
    <script>
    window.onload = () => {
      new Vue({
        data: () => {
          return {
            itr: 2
          }
        },
        el: '#vue'
      });
    }
    </script>
</head>
<body>
<section id="vue">
  <select v-model="itr">
    <option value="1">john</option>
    <option value="2">satoh</option>
    <option value="3">john.satoh</option>
  </select>
</section>
</body>
</html>

v-onディレクティブ

属性に、eventに対する振る舞いを指定することができます

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-onディレクティブについて1</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.min.js"></script>
    <script>
    window.onload = () => {
      new Vue({
        methods: {
          click: function() {
            console.log('clickしました');
          }
        },
        el: '#vue'
      });
    }
    </script>
</head>
<body>
<section id="vue">
  <p v-on:click="click">click1してください</p> <!--methodsに定義したclickメソッドを参照できます-->
  <p @click="click">click2してください</p> <!--v-on:は@にすることができます-->
</section>
</body>
</html>

記述した関数に引数を渡すことも可能です。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-onディレクティブについて2</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.min.js"></script>
    <script>
    window.onload = () => {
      new Vue({
        data: () => {
          return {
            name: 'satoh'
          }
        },
        methods: {
          hello: function(name) {
            console.log(`hello: ${name}`);
          }
        },
        el: '#vue'
      });
    }
    </script>
</head>
<body>
<section id="vue">
  <p @click="hello('john')">hello: john</p> <!--引数を入れることができます-->
  <p @click="hello(name)">hello: {{name}}</p> <!-- dataの値を入れることもできます -->
</section>
</body>
</html>

click以外にもkeyupなども使うことができます。ただし、v-modelとの競合に気をつけてください。

補足

ここまでのディレクティブを使用することで、画像を一定時間ごとに切り替えるスライドショーを作ることができます。

また、v-modelとv-onを使い、画像を動的に追加するなどと行った処理を追加するなどができます。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.min.js"></script>
    <script>
    window.onload = () => {
      const vm = new Vue({
        data: () => {
          return {
            urls: [
              'https://c2.staticflickr.com/6/5011/5560523513_2eda42dcb5_n.jpg',
              'https://c2.staticflickr.com/4/3893/15043995159_83894d7ed1_n.jpg',
              'https://c2.staticflickr.com/4/3179/2578145061_9d518deb42_m.jpg'
            ],
            itr: 0,
            url: ''
          }
        },
        methods: {
          addUrl: function() {
            this.urls.push(this.url);
            this.url = '';
          },
        },
        el: '#vue'
      });
      setInterval(() => {
        vm.itr = vm.itr === vm.urls.length - 1 ? 0 : vm.itr + 1;
      }, 1000)
    }
    </script>
</head>
<body>
<section id="vue">
  <div style="height: 200px;">
    <img style="height: 100%;" :src="urls[itr]">
  </div>
  <input v-model="url">
  <button @click="addUrl">追加</button>
</section>
</body>
</html>

まとめ

v-bind、v-on、v-modelで、データバインディングについて、大まかな説明が終わりました。

これにより、簡単なアプリケーションは作れるようになりました。

次回は、より複雑なアプリケーションを作成するためにv-ifなどのディレクティブについてお話したいと思います。

ありがとうございました。