🦚

【入門】Vue.jsを試してみた

2021/05/05に公開

Vue.jsとは

JavaScriptのフレームワークの1つで、効率よくフロントエンドの開発が行える。

  • 学習コストが低い。
    • CDNでjsファイルを読み込むだけで使用することができる。
    • シンプルにコードを書くことができる。
  • DOM操作を自動に行う
    • HTMLの要素とJSの値やイベントとの紐付けを自動で行ってくれる。
    • jQueryよりも容易にコーディングできる。

Hello World!

まず、Vue.jsで「Hello World!」を表示してみましょう。

  • CDNでVueを読み込む
    • <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">
  • Vueインスタンスの生成
    • new Vue({})
      • el: HTML側のid属性との対応づけをする。
      • data: 表示するデータなどを定義する。
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue.js入門</title>
</head>
<body>
  <div id="app">
    {{ message }}
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
    var app = new Vue({
      el: "#app",
      data: {
        message: "Hello World!"
      }
    });
  </script>
</body>
</html>

ディレクティブ

ディレクティブとは、接頭辞v-が付いたVue.jsに用意された特別な属性のことである。
もっと詳しく言うと、DOM要素に対して何か実行するものをライブラリに伝達する。
Vue.jsではこのディレクティブで始まりディレクティブで終わるとも言うくらい重要な概念となる。

※以下からソースコードはbody部のみを記載する。

v-bind

HTML側のある要素の属性を動的に設定することができる。

index.html
<body>
  <div id="app">
    <p v-bind:class="error_class">エラーが発生しました。</p>
    <!- 省略記法 -->
    <p :class="error_class">エラーが発生しました。</p>	  
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
    var app = new Vue({
      el: "#app",
      data: {
        error_class: "error"
      }
    });
  </script>
</body>

v-on

イベントリスナーを定義することで、Vueインスタンスのメソッドを呼び出すことができる。

index.html
<body>
  <div id="app">
    <p>{{ now }}</p>
    <button v-on:click="time">現在時刻を表示</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
    var app = new Vue({
      el: "#app",
      data: {
        now: "00:00:00"
      },
      methods: {
        time: function() {
          var date = new Date();
          this.now = date.getHours() + ":"
                   + date.getMinutes() + ":"
                   + date.getSeconds();
        }
      }
    });
  </script>
</body>

v-if

条件分岐によって、要素の有無の切り替えができる。
isErrorがtrueならば、エラーが発生しました。が画面に表示される。
isErrorがfalseならば、エラーが発生しました。が画面に表示されない。

index.html
<body>
  <div id="app">
    <p v-if="isError">エラーが発生しました。</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
    var error = new Vue({
      el: "#app",
      data: {
        isError: true
      }
    });
  </script>
</body>

v-once

Vue.jsによるレンダリング(画面描画)を一度のみ行うようにする。
Vueインスタンスの変数にアクセスするときはthis.変数名と記述する。

index.html
<body>
  <div id="app">
      <p v-once>{{ count }}回クリックされました</p>
      <button v-on:click="counter">カウントボタン</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
    var app = new Vue ({
      el: '#app',
      data: {
        count: 0
      },
      methods: {
        counter: function(){
          this.count++
        }
      }
    })
  </script>
</body>

v-for

配列であるデータの各要素を制御することができる。
拡張for文のような記法をv-forに記述する。
v-forを使用する場合は、v-bindのkeyプロパティの指定が必須である。
keyを指定しない場合は配列のindexがkey値に使用されるが、key として使用すべきではない。
→ 配列内の要素の追加・削除や順序の変更が行われるとき、index値も変化してしまう。

index.html
<body>
  <div id="app">
    <button v-on:click="shuffle">シャッフル</button>
    <ul>
      <li v-for="prefecture in prefectures" :key="prefecture.id">
        {{ prefecture.name }}
      </li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
  var app = new Vue({
    el: "#app",
    data: {
      prefectures: [
        { id:1, name: "福岡県" },
        { id:2, name: "佐賀県" },
        { id:3, name: "長崎県" },
        { id:4, name: "大分県" },
        { id:5, name: "熊本県" },
        { id:6, name: "宮崎県" },
        { id:7, name: "鹿児島県" }
      ]
    }
  });
  </script>
</body>

v-model

入力情報とデータの双方向データバインディングを簡単に行うことができる。
もっと詳しく言うと、テキストボックスの値(value属性値)が変更されると、dataで持っているtextの値に自動的に反映される仕組みがある。
v-modelは属性の初期値を無視するという特徴があるため、dataに初期値を持たせるカスタムディレクティブで独自に実装する必要がある。

index.html
<body>
  <div id="app">
    <p>{{ text }}</p>
    <input v-model="text">
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
    var app = new Vue ({
      el: '#app',
      data: {
        text: ''
      }
    })
  </script>
</body>

算出プロパティ

算出プロパティとは、関数で算出したデータを返すことができるプロパティのこと。
conputedをvueインスタンスに記述する。

index.html
<body>
  <div id="app">
    {{ fullName }}
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        firstName: 'Nobi',
        lastName: 'Nobita'
      },
      computed: {
        fullName: function() {
          return this.firstName + ' ' + this.lastName
        }
      } 
    })
  </script>
</body>

上記の例はmethodsでも同様なことができる。

index.html
<body>
  <div id="app">
    {{ getFullName() }}
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        firstName: 'Nobi',
        lastName: 'Nobita'
      },
      methods: {
        getFullName: function() {
           return this.firstName + ' ' + this.lastName
        }
      } 
    })
  </script>
</body>

conputed VS methods

conputed methods
記法(呼び出し) () 不要 () 必要
キャッシュ される されない
  • conputed
    • 引数を伴う処理ができない。
    • キャッシュ機能あり(=指定されているデータに変化があれば、再実行される)
  • methods
    • 引数を使った処理が可能である。
    • キャッシュ機能なし(=毎度毎度再実行される)
index.html
<body>
<div id="app">
  // conputed
    <ol>
    <li>{{ randomNum }}</li>
    <li>{{ randomNum }}</li>
    <li>{{ randomNum }}</li>
  </ol>

  // methods
  <ol>
    <li> {{ getRandomNum() }}</li>
    <li> {{ getRandomNum() }}</li>
    <li> {{ getRandomNum() }}</li>  
  </ol>
</div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script>
    var app = new Vue({
      el: "#app",
      computed: {
        randomNum: function () {
          console.log("computed");
          return Math.random();
        }
      },
      methods: {
        getRandomNum: function () {
          console.log("methods");
          return Math.random();
        }
      }
    });
  </script>
</body>

computedでは全て同じ値になるが、methodsは全て異なる値となる。

// computed
0.5562891327999486
0.5562891327999486
0.5562891327999486

// methods
0.10127439472454514
0.530424483259178
0.4696634887357811

computedではコンソールログには1度しかログが出ない。(1回しか呼ばれていない)

computedはリアクティブデータ(dataオプションに設定されているデータ)が更新されない限り、実行されない!!

参考

Discussion