実践
Vue.jsを使いこなす
第1回 Vue.jsとは

双方向データバインディングに特化したVue.jsは、シンプルで学習コストも低いといわれます。第1回目はVue.jsがフレームワークとして、どんな強みをもっているのか、その特徴をコードから概観します。

2015年01月29日発行
記事執筆時点のバージョンは0.11.4です。最新バージョンVue.js 2.0を元に書かれた「これから始めるVue.js 2.0」シリーズがあります。(2017年3月現在)

目次

本シリーズでは筆者お気に入りのJavaScriptアプリケーションフレームワークである、Vue.js(ビュージェイエス)の基本的な機能や使い方について解説します。

第1回目では、Vue.js*がどのようなフレームワークなのかと、Vue.jsを使うとどのようなことができるのかを紹介します。

*注:Vue.jsの開発状況

Vue.jsはまだ若い新進気鋭のフレームワークです。記事執筆時点のバージョンは0.11.4と、目下開発中です。アップデートによって破壊的な変更が加えられる可能性があり、この記事に書かれている方法が正しく動作しなくなることがあります。

なお、このシリーズで紹介するサンプルは次のリポジトリにまとめてあります。併せて、参照してください。

Vue.jsを使いこなす

シンプルなMVVMフレームワーク

Vue.jsはMVVMと呼ばれる設計パターンを採用しているフレームワークです。MVVMフレームワークではModelViewViewModel の3つでアプリケーションを構築します。このシリーズでは、設計パターンに関するややこしい話については触れません。

Vue.jsはシンプルさを売りにしています。MVVMを採用している有名なフレームワークとして、ほかにKnockout.jsがあります。Vue.jsはKnockout.jsよりわかりやすくシンプルなAPIを提供しています。またVue.jsのいくつかのAPIはAngularJSからの影響も受けています。

AngularJSはフルスタックなフレームワークで、何でもできますが、独特な文法や制約によって学習コストが高いとされています。一方、Vue.jsは双方向データバインディングを実現することに特化しているため、とてもシンプルにわかりやすく書くことができます。これが違いです。

機能こそAngularJSやKnockout.jsより少ないものの、そのシンプルさから、使いこなすための学習コストも低く、とても簡単にフレームワークの恩恵を受けることができるでしょう。

Vue.jsを使うにあたって

前述したとおり、Vue.jsは双方向データバインディングを行うのが主な役割です。Webアプリケーションを構築するのに足りない機能もありますが、Vue.jsがシンプルであるため、ほかのライブラリと組み合わせるのがとても簡単です。

例えば、Vue.jsにはURLのルーティングを行う機能がありませんが、ルーティング機能を実現したい場合にはpage.jsDirectorを使うことがVue.jsの公式ガイドで推奨されています

機能が足りないと考えるのではなく、好きなライブラリを自分で選択できると考えると、シンプルで機能が限定されていることが、Vue.jsを使う理由のひとつになることでしょう。

動作をサポートするブラウザ

Vue.jsはIE9以上の、モダンブラウザを対象として動作するように作られています。実装にECMAScript 5の機能が使われており、これをサポートしているブラウザで動作するようになっています。

モダンブラウザのみを対象にすることで、新しいフィーチャーを使った実装が可能になります。レガシーブラウザをサポートするためのポリフィルによるコード量の肥大化もありません。実装がシンプルになることでフレームワーク自体も軽量になり、動作の高速化にも繋がります。

AngularJSやKnockout.jsはレガシーブラウザをサポートしていますが、それゆえに動作が遅かったり、構文がシンプルでないといった面もあります。レガシーブラウザをサポートする必要がないならば、Vue.jsを選択するよい理由となるでしょう。

Vue.jsの動作例

Vue.jsは先行するJavaScriptフレームワークのよいところを取り入れて作られています。特にAngularJSと似たAPIを持っています。Vue.jsを使ってどのようなアプリケーションが書けるか、サンプルを例に見てみましょう。

ここでは、エンジニアの外村が書いた『攻略!AngularJSシリーズ』にあるサンプルを、Vue.jsを使って書き直したものを紹介します。

インクリメンタルサーチ

インクリメンタルサーチ

検索ボックスにテキストを入力すると、入力したテキストに応じて表示されているリストの項目がフィルタリングされるものです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Vue.js incremental search demo</title>
</head>
<body>
  <div id="app">
    <input type="search" placeholder="Search" v-model="searchText">
    <ul>
      <li v-repeat="people | filterBy searchText">{{firstName}} {{lastName}}
    </ul>
  </div>
  <script src="../../js/lib/vue.js"></script>
  <script src="app.js"></script>
</body>
</html>
var vm = new Vue({
  el: "#app",
  data: {
    people: [
      { firstName: 'Naohiro', lastName: 'Nakajima' },
      { firstName: 'Kazuhito', lastName: 'Hokamura' },
      { firstName: 'Takeshi',  lastName: 'Takatsudo' },
      { firstName: 'Akihiro',  lastName: 'Oyamada' },
      { firstName: 'Kazunori',  lastName: 'Tokuda' },
      { firstName: 'Yukihisa',  lastName: 'Yamada' }
    ]
  }
});

本来なら多くの処理を書く必要がある機能を、これだけの記述で実現できます。このサンプルコードを見ただけでも、Vue.jsのシンプルさを垣間見ることができるのではないかと思います。Vue.jsもAngularJS同様に、HTMLにテンプレートを記述してデータのバインディングを行いますが、コンポーネント(部品)として使いまわしやすいように、JavaScriptの中に記述することもできます。

機能の詳しい解説は次回以降行います。

双方向データバインディングとは

双方向データバインディングとは、データの変更があればUIの表示を更新し、UIの変更があればデータの更新を自動的に行う機能を指します。Vue.jsはこの双方向データバインディングをシンプルに行うことに重点を置いています。

双方向データバインディング

テキストボックスに入力した文字が、そのままテキストボックスの下にも表示されるというものです。入力した文字がHello XXXX!というぐあいに、XXXXの部分に入ります。

Vue.jsを使った場合、次にように書くことができます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Vue.js binding demo</title>
</head>
<body>
  <div id="app">
    <input type="text" v-model="name">
    <div>Hello {{name}}!</div>
  </div>
  <script src="../../js/lib/vue.js"></script>
  <script src="app.js"></script>
</body>
</html>
var vm = new Vue({
  el: "#app"
});

JavaScript側で行っているのはid="app"となっている要素を、ViewModelとして使うという宣言をしているだけです。HTML側ではinput要素にv-modelという独自属性を指定しています。

このv-model属性はVue.jsが用意しているディレクティブという機能のひとつです。inputなどのForm系の要素にv-modelという属性を使い、属性値としてViewModelの持っているプロパティ名を指定します。すると、その要素の値と、指定したプロパティの値が自動で同期されるようになります。

この例では、input要素にテキストを入力するたびに、ViewModelの持つnameプロパティの値が更新されます。値の更新とともに、nameプロパティを参照している{{name}}の部分の表示も自動で更新されます。

手動でinput要素の値の変更を監視する必要も、変更された値をUIに反映する必要もありません。このように宣言的な記述をするだけで、データとUIの同期が取れるのがMVVMフレームワークの強みです。

Vue.jsの機能と特徴

Vue.jsはシンプルな双方向データバインディングに特化しているといっても、機能が足りないといったことはありません。アニメーションを追加することもできますし、ディレクティブによる細かい動作の指定も行えます。

ここではいくつかの機能と特徴を簡単に紹介します。それぞれ詳しい解説は、次回以降で順次取り上げる予定です。

ディレクティブ

Vue.jsにはディレクティブ(directive)と呼ばれる組み込みの機能があります。これはHTMLに独自の属性を付与することで、DOM操作を行う機能です。

例えば、Modelの値とHTMLの表示を同期させたり、Modelの値に応じて要素の表示と非表示を切り替えたりといったことができます。Vue.jsでは、DOMで起こるイベントのハンドリングも、ディレクティブを使って行います。

ディレクティブは機能ごとに細かく、数多く用意されているので、ディレクティブを使いこなすことができれば、直接DOM要素を操作するコードを書く必要はなくなるでしょう。

自分で独自のディレクティブを定義することもできます。ディレクティブにはv-という、Vue.jsのプリフィックスが付いたHTMLの属性を利用します。

AngularJSにもディレクティブがありますが、Vue.jsのディレクティブとは異なるものです。Vue.jsには、AngularJSのディレクティブに近いものとして、v-componentというコンポーネント化を行う機能があります。

コンポーネント指向

UIコンポーネント(部品)を組み合わせてアプリケーションを作るというのが、Vue.jsの方向性です。Vue.jsにはコンポーネント化するための機能が多く備わっています。

また、Vue.jsは部品単位でアプリケーションを設計することを基本として設計されています。これは仕様策定中であるWeb Componentsを意識した作りになっていて、先を見据えた実装がされています。将来的にWeb Componentsの機能をシームレスに利用できるようになると予想しています。

学習コスト

簡単な使い方をするだけならば、学習コストはほとんどかからないのもVue.jsの強みでしょう。少し複雑なことをしたくなったとしても、わかりやすいAPIリファレンス使用例が用意されているので、AngularJSほど習得に苦労することはないと思います。

Vue.jsはAngularJSやBackbone.jsやKnockout.jsといったフレームワークのよい所を元に設計されているので、元になっているフレームワークの使用経験があれば、用語の定義や機能の違いはあっても使いこなすことができるでしょう。

コラム:制約がないということ

「制約がない」というのは、文法や、それによって実現できるコード設計の自由度が高いことを指します。制約がなく、シンプルで学習コストが低いのは、Vue.jsの大きな利点で、よいことだと思います。その反面、制約がないことから、各個人によって書き方に相違が出やすいことも意識しておいてほしいことです。

これはどのフレームワークを使う場合にも言えることですが、要件やチームなど、状況によって使用するフレームワークを選択するようにするとよいでしょう。

筆者は小さなアプリケーションを作るときや、データの更新とUIの更新の頻度が高いアプリケーションを作る際にVue.jsを使うようにしています。

おわりに

今回はVue.jsでできることや特徴などを簡単に紹介しました。次回以降、具体的な機能や詳しい使い方について紹介していきます。

次回は、ViewModelを中心に基本的な使い方を詳しく説明します。

中島 直博
中島 直博
フロントエンド・エンジニア

JavaScriptとCSSへの興味から大学院を中退してWebの世界に飛び込む。大手デジタルコンテンツベンダーにてHTML、CSS、JavaScriptなどフロントエンド全般の担当として、主にスマートフォン向けゲームの開発に従事。2014年1月にフロントエンド・エンジニアとして株式会社ピクセルグリッドへ入社。スマートフォンサイトの実装を得意とする。 また、在学中からhtml5jのスタッフとして、さまざまな技術系勉強会の運営に関わり、HTML5 Experts.jpのコントリビューターもつとめる。