
新たにフレームワークを導入しようとすると概念的な部分やケースによっては新たな言語など様々な学習コストがかかってきますが、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
と設定します。
<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
関数が実行されるようにします。
accordion__body
の部分はv-show
ディレクティブを使いexpand
データの値がtrue
かfalse
かを参照しています。v-show
は与えられた条件がtrue
の時にdisplay
で該当要素の表示・非表示を切り替えるため、expand
の値がtrueの時だけaccordion__body
が表示されます。
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
の値を反転します。これによってクリックされるたびに実行されますtrue
とfalse
が入れ替わります。
// ...
toggle: function() {
this.expand = !this.expand;
}
// ...
実行してみる
Vueインスタンスをはじめに作成した<div>
要素にマウントし、アコーディオンが表示されれば成功です。
// ...
var app = new Vue({
el: '#app'
});
// ...
まとめ
今回取り上げたものはVueの機能の極一部ですが、コンポーネントを利用することによってちょっとした動的機能ならサクッと作れてしまうのがお分かりいただけたかと思います。最初はVue特有の記述方法や概念的なものに戸惑いを覚えるかもしれませんが、ある程度覚えてしまえば効率的に開発を進められるのが強みですのでぜひ実践していただければと思います。今後はさらにWebpackとの連携方法なども紹介していきたいと思います。