こんにちは、新入社員のNakataです。入社するまでは生物系の研究をしていましたが、この度Orizuru開発に携わることになりました。そんな私の初めての実務として、既存のアプリケーションをシングルページアプリケーション(SPA)に移行する作業を行いました。実装には、SPAを効率的に開発するためのフレームワークVue.jsを使いました(Vue.js公式サイト)。
今回はそもそもSPAとは、Vue.jsとはどんなものなのかを、私自身の理解のため、これからSPA開発や Vue.jsを学ぶ人たち向けに、簡単にまとめました。また、SPA移行で役に立った機能(vue-router)の紹介もしたいと思います。
SPAとは
SPA(Single Page Application)とは、名前の通り単一のページで構成されるアプリケーションになります。SPAではない webアプリケーションでは、ページ遷移を行う度サーバーからHTMLを取得し、それを表示することで画面を書き換えていました。SPAでは、サーバーからHTMLを受け取るのは最初だけで、それ以降はAjaxでデータをやり取りし、JavaScriptでDOM(HTML文書やXML文書を書き換える機能を使用するための仕組み)を操作することで画面を書き換えます。初期ページのローディングには時間がかかりますが、それ以降はAjax通信のみで画面の書き換えを行うため、ページ遷移が早くなりサーバーへの負荷も減ります。
なぜVue.js?
Vue.jsには、コンポーネント指向や双方向データバインディングのように、SPAの開発を進めやすい特徴があります。また、公式のAPIリファレンスや使用例が充実しているため、開発に必要なものを効率よく学習できます。そこで今回はVue.jsを使用しました。
Vue.jsの特徴
画像引用元:Vue.jsの作者Evan氏によるスライド資料
実際に触ってみる
環境設定
今回はVue.jsを使ってみるため、プロジェクトのテンプレートを自動で作成してくれる、vue-cliを使用します。
vue-cliを使用するためにはNode.jsが必要です。Node.jsをインストールしておいてください。準備ができたら以下のコマンドでvue-cliをインストールします。
1 |
$ npm install -g vue-cli |
様々なテンプレートが用意されていますが、今回はwebpack(複数のファイルを1つにまとめて出力するツールの一種)でプロジェクトを作成します。途中、設定を確認されますがEnterで進めます。
1 |
$ vue init webpack my-project |
これで設定完了です。実際にサーバを動かしてみましょう。
1 2 3 |
$ cd my-project $ npm install $ npm run dev |
データバインディングを使ってみる
Vue.jsでは、v-modelディレクティブを用いることで、input要素に対して、双方向データバインディングが可能となります。ディレクティブとは、 DOM要素に対して何かを実行するコマンドの役割をもつトークンで、HTMLのタグ内に記述します。
実際に使ってみるため、今回作成したプロジェクト内に作成された、srcディレクトリ内のファイルを見ていきましょう。
まずは、src/components/HelloWorld.vueのtemplateタグ内を、以下のサンプルコードに置き換えてみてください。
サンプルコード
1 2 3 4 5 6 |
<div class="hello"> <h1>{{ msg }}</h1> <input type="text" v-model="msg"> </div> |
src/components/HelloWorld.vue内のscriptタグ内は以下のようになっています。
Vueコンポーネント内のdataはオブジェクトではなく、オブジェクトを返す関数として定義します。
1 2 3 4 5 6 7 8 |
export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } } } |
コードの置き換えと確認が終わったら保存を行い、実際にフォームから値を入力してみましょう。
data.msgとinputの要素が、v-modelディレクティブで紐付けされていることで、動的にUIが更新されることが確認できたでしょうか。このようにVue.jsでは、双方向データバインディングを簡潔に実装することが可能です。
vue-routerを使ってみる
Vue.jsでは画面描画のために、URLを変える必要はありません。しかし、URLの変化と画面の書き換えを対応させておくことで以下のようなメリットもあります。
- 対応するURLをブックマークとして保存可能
- SPAでないアプリケーションをSPAへ移行する際、元々のURLごとに画面を対応させることが可能
- URLごとにコンポーネント単位で開発を進めることが可能
vue-routerを使用することで、ページ間の遷移および、それに対応するURLの変更が可能となります。では、vue-router使ってURLを変化させ画面の書き換えを行ってみましょう。src/router/index.jsを、以下のサンプルコードに書き換えてみてください。
サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import PageA from '@/components/PageA' import PageB from '@/components/PageB' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld }, { path: '/PageA', name: 'PageA', component: PageA }, { path: '/PageB/:msg', name: 'PageB', component: PageB, props: true } ] }) |
importでコンポーネントの読み込み、pathでコンポーネントごとにルートを設定しています。pathで設定したURLにアクセスすることで、そのコンポーネントの画面が表示されるようになります。propsについては後ほど説明します。
次にvueファイルを作成します。src/components以下にHelloWorld.vueをコピーして、PageA.vue、PageB.vueを作成し、templateとscriptタグ内を以下のサンプルコードに置き換えてみてください。HelloWorld.vueについても同様に置き換えてください。
サンプルコード
PageA.vue
1 2 3 4 5 6 7 8 |
<div class="hello"> <h1>PageA</h1> <router-link to="/">HelloWorld</router-link> </div> |
1 2 3 |
export default { name: 'PageA', } |
PageB.vue
1 2 3 4 5 6 7 8 9 10 11 |
<div class="hello"> <h1>PageB</h1> <h1>{{ msg }}</h1> <router-link to="/">HelloWorld</router-link> </div> |
1 2 3 4 |
export default { name: 'PageB', props: [ 'msg' ] } |
HelloWorld.vue
1 2 3 4 5 6 7 8 9 10 |
<div class="hello"> <h1>{{ msg }}</h1> <input type="text" v-model="msg"> <router-link to='/PageA'>PageA</router-link> <router-link :to="'/PageB/' + msg">PageB</router-link> </div> |
コードの置き換えと確認が終わったら保存を行い、リンク部分をクリックして画面とURLが変化しているか確認してみましょう。
router-linkタグでリンクの設定をすることが可能です。toでrouter/index.jsのpathで設定したリンク先を指定します。aタグのような感覚で使えますが、サーバーからのHTMLの取得は行われません。
次にpropsについてですが、propsとは子コンポーネントで親のデータを参照したい時に、データを子コンポーネントに渡すためのオプションです。router-linkタグ内のtoの前に:を付けバインディングされたデータの値を渡すことができます。router/index.jsのpathで’/PageB/:msg’と定義していますが、/PageB/以下の値をPageBコンポーネントでmsgの値として受け取るという設定です。PageB.vueのscriptタグ内でprops: [ ‘msg’ ]を定義することでPageBコンポーネント内で受け取ったmsgの値が利用できます。
このようにvue-routerを利用することでURLごとに画面を書き換えることができます。
最後に
今回はVue.jsやその一部機能について簡単に紹介させていただきました。私自身もVue.jsを触り始めたばかりですので、学習やアプリケーションの開発を通して、より理解を深めていきたいです。次回以降は、SPA開発で役に立つ、コンポーネントの作成方法や、各ディレクティブの機能等について紹介できればと思います。