• Subscribe to RSS

Vue.js導入の最初の1歩

2020.05.27

トリ

Vueなどのフレームワークに興味はあるけれど、まずはどのような感じで動くのかを知りたいという方に読んでいただければと思います。

新たにフレームワークを導入しようとすると概念的な部分やケースによっては新たな言語など様々な学習コストがかかってきますが、VueはAngular・React等他のメジャーなフレームワークと比較しても学習コストはそこまで高くなく、JavaScriptの知識さえあればサクッと導入できるという利点があります。またチーム内でjQueryもまだまだ活発に使用されており、今までjQueryで実装していた時の考え方も活かしやすいという点で今回チームメンバーにVueを紹介してみました。

Vue.jsの読み込み

今回はVue.js(以下Vue)のコンポーネント機能を使ってシンプルなアコーディオンを実装してみたいと思います。なるべく分かりやすくなるようにNPMなどのパッケージ管理ツールは敢えて使わず<script>タグでVue.jsを読みます。

開発バージョンのVueを読み込んでおくとデバッグなどに便利なデベロッパーツールVue Devtoolsを利用することができます。各ブラウザ用の拡張機能になっていますので、適宜インストールしてください。

※本記事では執筆時点での最新バージョン2.6.10を使用します。

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>

HTML

アコーディオンの配置とディレクティブの設定

Vueのインスタンスをマウントしたい要素を用意しておきます。タグの種類・id名は自由ですが、今回は一般的によく使われるappというidを持った<div>を使用します。

<div id="app"></div>

アコーディオン本体になる部分(コンポーネント)を記述します。<accordion>タグで囲まれた部分が単体のアコーディオンとなります。タイトルと本文を別々で設定できるように、予めそれぞれ独立した<template>タグでマークアップしておきます。

<div id="app">
    <accordion>
        <template>TITLE</template>
        <template>Nullam a urna et neque molestie commodo placerat et odio.</template>
    </accordion>
</div>

Vueのtemplateオプション(後述)に対応させるため、名前付きのv-slotディレクティブでタイトルとなる部分にv-slot:title、本文となる部分にv-slot:bodyと設定します。

参考:v-slot

<div id="app">
    <accordion>
        <template v-slot:title>TITLE</template>
        <template v-slot:body>Nullam a urna et neque molestie commodo placerat et odio.</template>
    </accordion>
</div>

JavaScript

テンプレート

まずはVueに対してアコーディオンのコンポーネントを登録します。accordionというコンポーネント名で登録しました。

参考:コンポーネントの登録

Vue.component('accordion', { /* ... */ });

HTMLセクションで設置した<template>タグを置き換えるHTMLをtemplateオプションで設定します。ここで設定する<slot>要素はname属性をv-slotディレクティブの名前と一致させておくことで置き換えることができます。

Vue.component('accordion', {
  template: `
    <div class="accordion">
      <h2 class="accordion__title">
        <slot name="title"></slot>
      </h2>
      <div class="accordion__body">
        <slot name="body"></slot>
      </div>
    </div>
    `
});

出力されるHTMLイメージ

<div class="accordion">
  <h2 class="accordion__title">TITLE</h2>
  <div class="accordion__body">Nullam a urna et neque molestie commodo placerat et odio.</div>
</div>

データ

アコーディオンの開閉状態を制御するためのデータをオプションで追加します。expandという名前で真偽値を持つデータを1つコンポーネントに追加しました。デフォルトでは閉じた状態にするためfalseを設定しています。

Vue.component('accordion', {
  template: `
    <div class="accordion" :class="{ open: expand }">
      <h2 class="accordion__title" @click="toggle()">
        <slot name="title"></slot>
      </h2>
      <div class="accordion__body" v-show="expand">
        <slot name="body"></slot>
      </div>
    </div>
    `,
  data: () => {
    return {
      expand: false
    };
  }
});

コンポーネント内のdataオプションは必ず関数で作成しなければならないため、オブジェクトを返す関数を指定します。

// ...
data: () => {
    return {
      expand: false
    };
  },
// ...

イベントハンドリング

アコーディオンの動きを実行するイベントハンドラの設定をmethodsオプションで指定します。今回はtoggleという名前のメソッドで設定しました。

accordion__titleの部分がクリックされる度に開閉されるようにh2の要素にv-onディレクティブでtoggle関数が実行されるようにします。

参考:v-on

accordion__bodyの部分はv-showディレクティブを使いexpandデータの値がtruefalseかを参照しています。v-showは与えられた条件がtrueの時にdisplayで該当要素の表示・非表示を切り替えるため、expandの値がtrueの時だけaccordion__bodyが表示されます。

参考:v-show

Vue.component('accordion', {
  template: `
    <div class="accordion">
      <h2 class="accordion__title" v-on:click="toggle()">
        <slot name="title"></slot>
      </h2>
      <div class="accordion__body" v-show="expand">
        <slot name="body"></slot>
      </div>
    </div>
    `,
  data: () => {
    return {
      expand: false
    };
  },
  methods: {
    toggle: function() {
      this.expand = !this.expand;
    }
  }
});

toggle関数内は実行されるとexpandの値を反転します。これによってクリックされるたびに実行されますtruefalseが入れ替わります。

// ...
    toggle: function() {
      this.expand = !this.expand;
    }
// ...

実行してみる

Vueインスタンスをはじめに作成した<div>要素にマウントし、アコーディオンが表示されれば成功です。

// ...
var app = new Vue({
  el: '#app'
});
// ...

まとめ

今回取り上げたものはVueの機能の極一部ですが、コンポーネントを利用することによってちょっとした動的機能ならサクッと作れてしまうのがお分かりいただけたかと思います。最初はVue特有の記述方法や概念的なものに戸惑いを覚えるかもしれませんが、ある程度覚えてしまえば効率的に開発を進められるのが強みですのでぜひ実践していただければと思います。今後はさらにWebpackとの連携方法なども紹介していきたいと思います。