242
273

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

サーバレス構成の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操作から開放されることがよい。

242
273
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
242
273

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?