2016/09/30に2.0がリリースされてから、現在2017/03/05まででダウンロード数約3倍の増加をみせるVue.js。
npmtrends(2016/09/25 32,043 → 2017/03/05 109,774)
そろそろ無視出来ない勢いなので、とりあえず触ってみることにしました。 ドキュメントもしっかり日本語化されてるので英検4級の私にはありがたい。←ここ重要
1. 下準備
vue-cliを使ったほうがかなり楽そうなんですが、めんど(ry
ファーストステップなのでVue.jsのみでやってみたいと思います。
またCSS書くのもめんど(ry
久しぶりにbootstrap触りたくなったのでそれ使います。
ということでCodePenだけで準備完了です。すばらしい。pugも使える。CodePenありがとう。
2. とりあえずhtmlを組んでいく
元テンプレートはこちら
div.container h1 vue tab sample ul(class="nav nav-tabs" role="tablist") li(class="nav-item" role="presentation") a(href="#home" class="nav-link active" role="tab") ホーム li(class="nav-item" role="presentation") a(href="#test" class="nav-link" role="tab") テスト div.tab-content div(id="home" role="tabpanel") h2 HOME p ホームタブコンテンツ div(id="test" role="tabpanel") h2 TEST p テストタブコンテンツ
まず
<slot>
を使ってhtml側で管理する内容と、vue側で管理する内容を分離していきましょう。ここでは、テキスト内容をhtml、そのほかのものはvue側で管理させるようにしました。
(サンプルではわかりやすいようにnameをつけてますが、なくてokです)
div#v-root.container h1 vue tab sample tabs div(slot="tabContents") tab(name="home" text="ホーム" v-bind:selected="true") div(slot="tabinner") h2 HOME p ホームタブコンテンツ tab(name="test" text="テスト") div(slot="tabinner") h2 TEST p テストタブコンテンツ
Vue.component('tabs', { template: ` <div> <ul class="nav nav-tabs" role="tablist"> <li class="nav-item" role="presentation"> <a href="#home" class="nav-link" role="tab">ホーム</a> </li> <li class="nav-item" role="presentation"> <a href="#test" class="nav-link" role="tab">テスト</a> </li> </ul> <div class="tab-contents"> <slot name="tabContents"></slot> </div> </div> ` }); Vue.component('tab', { template: ` <div :id="'#' + this.name" role="tabpanel"><slot name="tabinner"></slot></div> `, props: { name: { required: true }, }, }); new Vue({ el: '#v-root' });
See the Pen Vue tab sample 03 by 35n139e (@35n139e) on CodePen.
3. Vue実装開始
tab実装
タブコンテンツを軸にタブリストを生成する方法で実装していきます。
html側でid名やタブのテキストを管理するので、props
にtext(テキスト)とname(id名)、selectedでデフォルトで開くタブを選べるようにしました。
tab(name="home" text="ホーム" v-bind:selected="true") div(slot="tabinner") h2 HOME p ホームタブコンテンツ tab(name="test" text="テスト") div(slot="tabinner") h2 TEST p テストタブコンテンツ
Vue.component('tab', { template: ` <div :id="'#' + this.name" role="tabpanel" v-if="isActive"> <slot name="tabinner"></slot> </div> `, data() { return { isActive: false }; }, props: { text: { required: true }, name: { required: true }, selected: { default: false } }, mounted() { if(location.hash != ""){ const url = location.hash; this.isActive = (url == '#' + this.name); }else{ this.isActive = this.selected; } } });
tabs実装
つぎにタブリストの生成です。
Vue.component('tabs', { template: ` <div> <ul class="nav nav-tabs" role="tablist"> <li v-for="tab in tabs" class="nav-item" role="presentation"> <a :href="'#' + tab.name" @click.prevent="selectTab(tab)" role="tab" class="nav-link" :class="{ 'active': tab.isActive }">{{ tab.text }}</a> </li> </ul> <div class="tab-content"> <slot name="tabwrap"></slot> </div> </div> `, data() { return { tabs: [] }; }, created() { this.tabs = this.$children; }, methods: { selectTab(selectedTab) { this.tabs.forEach(function(tab){ tab.isActive = (tab.name == selectedTab.name); }); } } });
v-for
でタブコンテンツの中を見に行かせます。
<li v-for="tab in tabs" class="nav-item" role="presentation">
タブリストの中身はそれぞれtabのpropsを参照させます。タブのアクティブ化は'v-bind:class'で行います。
<a :href="'#' + tab.name" @click.prevent="selectTab(tab)" role="tab" class="nav-link" :class="{ 'active': tab.isActive }">{{ tab.text }}</a>
タブリストをクリックしたときの関数をmethodsに記述。 それぞれのtab.nameとクリックしたtab.name(selectedTab.name)にアクティブフラグを立てさせます。
methods: { selectTab(selectedTab) { this.tabs.forEach(function(tab){ tab.isActive = (tab.name == selectedTab.name); }); } }
完成
tabsとtabを合わせるとあら不思議。タブの完成です。
See the Pen Vue tab sample 04 by 35n139e (@35n139e) on CodePen.
4. <transition>で味付け
最後に<transition>
を使って味付けしていきます。
animationのcssはAnimate.cssを利用させてもらいます。
下記のようにカスタムすれば<transition>
でAnimate.cssを直接使うことができます。
<transition name="animateCSS" enter-active-class="animated fadeIn" leave-active-class="hide" > <div :id="'#' + this.name" role="tabpanel" v-if="isActive"> <slot name="tabinner"></slot> </div> </transition>
これでアニメーションさせたいコンテンツをラッピングして終了です。簡単!キレイ!
See the Pen Vue tab sample 3 by 35n139e (@35n139e) on CodePen.
5. 最後に
Vue.jsはガイドもしっかりしてるし、学習コストも低めなので「Jqueryしか書いたことないよ」って方もぜひ触ってみていただきたいフレームワークです。
私もお試しで触ってみてハマった口で、今週の月曜日に弊社の採用サイトをVue.jsで作り直しました。ぜひそちらのほうも見ていただければと思います。