Posted at

サーバレスアプリ開発をjQueryでがんばらないためのVue.js

More than 1 year has passed since last update.

サーバレス構成のWebアプリ開発を担当し、そこでVue.jsを使ってみたので採用した経緯と、Vue.jsの何を使ったかを紹介する。


これまでのWebアプリ開発

JavaのWebアプリ開発ならThymeleafやFreemarkerなどのテンプレートエンジンを使用していた。

サーバレスだと、HTMLとJavaScriptで表示の処理を行うため、JavaScriptの処理が増える。

よく使われるのはjQueryによってDOMを操作し、HTMLを動的に変更する方法だろう。


jQueryのDOM操作は辛いよ

jQueryを使ったことがあればお分かりだと思うが、jQueryによるDOM操作は「このイベントで、このvalueがxxxなら、このDOMを変更する」という手続き型のコードになる。

JavaScriptの処理が増えると、この手続き型のコードが増えてデータと状態の管理が煩雑になる。

また、JavaScript側に表示の処理があるためHTMLを簡単に変更できない。


そこでVue.jsですよ

SPAっぽい要件なので、SPAに適したJavaScriptフレームワークを使う方がよさそう。

SPAがやりたいわけではないが。

Vue.jsは社内で検証の候補になっていたので採用してみた。

公式ガイドをさらっと読むと、HTMLに値を埋め込める、条件分岐、ループを組み込めるので、テンプレートエンジンと同じことができそう。

クライアントの開発は一任されていたので、試しやすかったのもある。


Vue.jsのはじめかた

お手軽にはじめるなら script タグに1行追加するだけ。


HTML

<!-- 開発バージョン(警告出力とデバッグモードあり) -->

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


HTML

<!-- 本番バージョン(警告出力なし、圧縮済み -->

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

但し、webpackでビルドが必要な機能は使えない。例えば単一ファイルコンポーネント。

単一ファイルコンポーネントはHTMLを構成するヘッダ、ボディなどを部品ごとに分けて扱える。

便利ではあるが、Node.jsのツール(npm, webpack, vue-cli)が必要になる。

公式ガイドでは、最初は script から使用することをおすすめしている。

機能数も少ないので script から使用する。


Vueのアプリ開発


Vueインスタンスの作成

画面ごとにHTMLを分けたので、HTMLごとにルートVueインスタンスを生成。

Vueインスタンスで使用するオプションは el, data, methods, computed のみ。


JavaScript

var vm = new Vue({

el: '#app',
data: {
items: [
{
isbn: '4873118069',
title: 'サーバーレスシングルページアプリケーション',
publisher: 'オライリージャパン',
price: 2808
},
{
isbn: '4798155160',
title: 'AWSによるサーバーレスアーキテクチャ',
publisher: '翔泳社',
price: 3888
}
]
},
methods: {
// メソッド
},
computed: {
// 算出プロパティ
}
})


el

Vueインスタンスの対象となるHTML要素を指定する。

data

バインドする変数を格納する。変数の値が変更されるとHTMLに反映される。

methods


v-on で呼び出す関数を記述する。

computed

算出プロパティ。依存するものが更新されなければ以前計算された結果を返す。


HTMLにJavaScriptの値を埋め込む

Vueインスタンスの data の変数を {{変数}} のように2重の中括弧で囲むとHTMLに値が埋め込める。

変数を処理させて表示する場合は算出プロパティを使用する。

例えば、合計金額を算出して表示するには以下のように記述する。


JavaScript

var vm = new Vue({

el: '#app',
data: {
items: [
{
isbn: '4873118069',
title: 'サーバーレスシングルページアプリケーション',
publisher: 'オライリージャパン',
price: 2808
},
{
isbn: '4798155160',
title: 'AWSによるサーバーレスアーキテクチャ',
publisher: '翔泳社',
price: 3888
}
]
},
methods: {
// メソッド
},
computed: {
priceTotal: function() {
var total = 0;
for (var item in items) {
total += item.price;
}
return priceTotal;
}
}
})


HTML

合計金額:{{priceTotal}}



ディレクティブの使い方

Vue.jsはHTMLタグの中にディレクティブという特別な属性を埋め込むことでHTMLを制御する。

使用したディレクティブは以下の通り。


v-if

条件で表示を切り替えるのに使用する。

v-show も同じ用途で使用されますが、v-show はCSSの display: none で表示を隠すのと同じでDOMは消えない。

DOMの追加、削除がない分、描画は v-show の方が早い。

例えばログインユーザの権限で表示項目を変える場合はDOMに出したくないから v-if の方がよさそう。

プルダウンやラジオボタンで項目を切り替えるのであれば、v-show の方がよさそう。


v-for

data の配列データを1件ずつループで処理するのに使用する。

例えばAjaxでDBから取得したデータを一覧表示する場合に使用される。

一覧を10件ずつ表示する場合は算出プロパティを使用するとよさそう。


JavaScript

var vm = new Vue({

el: '#app',
data: {
items: [], // AjaxでDBから取得
pagination: {
page: 0,
pageSize: 10,
},
startPage: 0,
pageSize: 10,
},
methods: {
// メソッド
},
computed: {
pageItems: function () {
var startPage = this.pagination.page * this.pagination.pageSize;
return this.items.slice(startPage, startPage + this.pagination.pageSize);
},
}
})


HTML

<table>

<thead>
<tr>
<th>ISBN</th>
<th>タイトル</th>
<th>出版社</th>
<th>値段</th>
</tr>
</thead>
<tbody>
<tr v-for="item in pageItems">
<td>{{item.isbn}}</td>
<td>{{item.title}}</td>
<td>{{item.publisher}}</td>
<td>{{item.price}}</td>
</tr>
</tbody>
</table>


v-bind

タグの属性に値を埋め込むのに使用する。

例えば class の属性を動的に切り替えるには <div v-bind:class="disabled: isDisabled"></div>のように記述すると dataisDisabled がtrueの場合に disabled が埋め込まれる。

v-bind:class:class のように省略して記述することもできる。

また、v-for と組み合わせて動的にセレクトボックスを作ることができる。


HTML

<select>

<option v-for="item in items" :value="item.isbn">{{item.title}}</option>
</select>


v-on

イベントで methods に記述した関数を呼び出すのに使用する。

例えばボタンクリック時のイベントは v-on:click="ファンクション名" のように記述する。

また、@click="ファンクション名" のように省略して記述することもできる。


v-model

input, select, textarea の値を data の変数にバインドするのに使用する。


v-cloak

v-cloak を使うことで、値が埋め込まれるまで {{変数}} がそのまま表示されるのを防ぐことができる。

CSSで display: none を適用しておきます。


CSS

[v-cloak] {

display: none;
}


まとめ

サーバレス構成だとJavaScriptフレームワークは必須かなと思う。

ReactやAngularは分からないが、Vue.jsは使いやすい。

何よりDOM操作から開放されることがよい。