タケハタのブログ

プログラマの生き方、働き方、技術について雑多に書いていくブログです。

JavaScript嫌いなサーバーエンジニアがVue.jsを触ってみた

きっかけ

先月のCEDEC 2018にて、グリーさんの「モバイルゲームのお問い合わせ対応にてAIチャットボットを導入してお問い合わせ件数を約20%削減した話」というセッションでのお話がきっかけでした。
https://2018.cedec.cesa.or.jp/session/detail/s5aab885981384

このセッションはタイトルの通り、お問い合わせ対応にチャットボットを導入した事例の紹介です。
その中で使用した技術の説明もあったのですが、そこでユーザーさんからのお問い合わせのインターフェースはWebで作り、技術としてはVue.jsを使用してサーバーエンジニアが作っていたというお話がありました。

そしてVue.jsを選んだ理由の一つとして「ReactよりもHTMLソースが読みやすい、初期学習のコストが低い」ということが挙げられており、Webフロントの開発にアレルギーのあった自分にはちょうどいいのでは、と思い興味を持ったのが今回触り始めたきっかけでした。
サーバーエンジニアもWebフロントそれなりに分かってないとなぁ・・・という危機感もあり。

筆者のWebフロントのレベル感

ぶっちゃけJQueryで時代が止まってました笑
それも割と基本的なレベルで。

2013年頃のJSのブームが来た頃に覚えようとしたけど、それすらも基本的なところまでしかやっていなかったし、あのDOMをゴチャゴチャいじる感じで嫌いで抵抗感が・・・
そしてAngularJSとか色々フレームワークが出てきたけど、このレベル感で触っても分からないだろうと勝手に思い込み敬遠してきました。
ということで完全に浦島太郎状態です。

主に使った資料

基礎から学ぶ Vue.js cr-vue.mio3io.com

Vue.js公式ドキュメント jp.vuejs.org

Webにも情報はいっぱいありますが、書籍の方が勉強は捗るタイプなので、ちょうど良さそうなレベル感で評判の良かった「基礎から学ぶ Vue.js」を購入。
あとは公式ドキュメントも日本語で充実した情報があるのでありがたいです。

Vue.jsとは?

詳しくはこちらの公式ドキュメントを読んでいただくのが良いと思いますが jp.vuejs.org

JavaScriptのフレームワークで、主にView部分をの開発をしやすくすることを目的としたものなのかなと思っています。
なので前述のCEDECのセッションでもあったように、Webフロントに慣れていないサーバーエンジニアが触っても取っ付きやすいものになっているのかなと。

触ってみる

まずはHello World!

下記のHTMLファイルを作ります。
一旦シンプルにHTML内にJavaScriptのコードも記述しています。

<html>
<body>
<div id="app">
    <!-- ⑤Vueで設定したデータを表示 -->
    {{ message }}
</div>
<!-- ①CDNからvue.jsの読み込み -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script>
// ②Vueインスタンスを生成
var app = new Vue({
    el: '#app', // ③appのブロックと紐づけ
    data: {
      message: 'Hello World!' // ④messageに値を設定
    }
})
</script>
</body>
</html>

このHTMLをブラウザで開くと、「Hello World!」が画面に表示されます。
コードのコメントに書いてある番号に沿って簡単に説明します。

①CDNからvue.jsの読み込み
ローカルにダウンロードして読み込むこともできますが、今回は手軽に触ってみるだけなのでCDN上にあるvue.jsを読み込んで使います。
vue@の後ろに書いている数字がバージョンの指定になります。

②Vueインスタンスを生成
Vueインスタンスを生成することで、Vueアプリケーションを作成します。
このコンストラクタの中で色々なオプションを設定することで、アプリケーションを構成することができます。
app という名前で変数化しており、こちらはコンソールからアクセス(後述)するのに使うことができますが必須ではないようです。

③appのブロックと紐づけ
el というオプションで、要素に紐づけます。
今回は <div id="app"> にこのVueインスタンスが紐付けられます。
(これをmountと言うようです)

④messageに値を設定
data というオプションで、アプリケーション内で使用するデータを定義することができます。

⑤Vueで設定したデータを表示
el で紐づけた要素 app のブロック内で、 data で定義したデータ message を呼び出して表示します。
{{ }} で囲うmustache形式で、データを呼ぶことができます。
el で紐づけた要素内でのみ扱えて、 <div id="app"> のブロックの外に書いてしまうと呼び出せないので、注意してください。

別ファイルへ切り出し

コード量も多くないので一旦1つのHTMLファイルにスクリプトも書き込みましたが、別ファイルを切り出す場合は下記のようになります。

index.jsというファイルを作り(名前は任意)、HTMLファイルと同一フォルダに置き

var app = new Vue({
    el: '#app',
    data: {
      message: 'Hello World!'
    }
})

HTMLの直接スクリプトを書いていた部分を下記のように変える

<html>
<body>
<div id="app">
    {{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script src="index.js"></script>
</body>
</html>

(普段JavaScript触ってないと忘れがちなので一応)

データバインディング

次はVue.jsの売りっぽい機能として挙げられるデータバインディングについて。
実はこれは先ほどのコードで既にやっています。

data: {
  message: 'Hello World!'
}
<div id="app">
    {{ message }}
</div>

ここの部分ですね。
Vue.jsでは、 data で定義されたデータがリアクティブデータとして扱われ、データを変更した際にそれを検知して、DOMの更新等の処理を自動的にやってくれます。
リアクティブデータは、細かい説明は省きますが「基礎から学ぶ Vue.js」から引用すると、

Vue.jsによって取得したとき(get)と代入したとき(set)のフック処理が登録された、反応のできるデータのことをいいます。

です。

言葉だと分かりづらいので実際にやってみましょう。
先ほどのHTMLを表示していたブラウザでコンソールを立ち上げます。
Google Chromeだと alt+command+I (Mac)で下記の画面が立ち上がります。

f:id:take7010:20180909134017p:plain

ここのConsoleタブで、 app.message="Hello Vue.js!" と入力してEnterキーを押します。

f:id:take7010:20180909134551p:plain

すると、画面上に表示されているメッセージも Hello Vue.js! に更新されたと思います。
これは前述したように、 data で定義された値を更新すると、それと同時にVue.js側でDOMの情報等も更新してくれているためです。

コンソールだとピンと来づらいかもしれないのでプログラムでも。
先ほどのindex.jsを下記のように書き換え、methodsを追加します。

var app = new Vue({
    el: '#app',
    data: {
      message: 'Hello World!'
    },
    methods: {
        updateMessage: function() {
            this.message="Hello Vue.js!"
        }
    }
})

methodsは文字通りアプリケーション内で使用したいメソッドを定義するオプションです。
ここでは updateMessage という名前で message のデータを更新するメソッドを定義しています。

さらに、HTMLファイルを下記のように書き換えます。

<html>
<body>
<div id="app">
    {{ message }}
    <button v-on:click="updateMessage">メッセージを更新</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script src="index.js"></script>
</body>
</html>

更新ボタンを追加し、先ほど作った updateMessage メソッドを紐付けました。
v-on:click という属性を使うことで、クリックした際にVueアプリケーション内のメソッドを呼び出せるようになります。
Vue.jsでは v-on というディレクティブをイベントハンドリングに使います。

これで画面に

f:id:take7010:20180909140256p:plain

と更新ボタンが表示され、クリックすると先ほどコンソールでやったのと同じように、メッセージが更新されるようになりました。
これを生のJavaScriptで書くと

var el = document.getElementById('app')
el.innerText = 'Hello Vue.js!'

みたいなまどろっこしいことをしなくちゃならなくて、これを見て昔JavaScriptでDOMを構築することに嫌悪感を覚えるようになり、これまでWebフロントの技術を敬遠するようになったきっかけになりました笑
(JQueryもちょっとラッピングはされてるけど、似たような手順を踏まないといけないのは変わらなかったので・・・)

配列のデータバインディング

テキストの書き換えだけでは面白くないのでもう一つ。
Vue.jsで配列を扱ってみます。
下記のHTML、JavaScriptファイルを作ります。

<html>
<body>
<div id="app">
    メンバーリスト
    <ul>
        <li v-for="member in memberList">{{ member }}</li>
    </ul>
    <input v-model="name">
    <button v-on:click="addMemberList">リストに追加</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script src="list_sample.js"></script>
</body>
</html>
var app = new Vue({
    el: '#app',
    data: {
      memberList: [
          '松井珠理奈', '須田亜香里', '宮脇咲良'
      ],
      name: ''
    },
    methods: {
        addMemberList: function() {
            this.memberList.push(this.name)
            this.name = ''
        }
    }
})

こんな画面が表示されます。

f:id:take7010:20180909175332p:plain

ここでは li タグの中で v-for というディレクティブを使っています。
これを使うと、JavaScriptのfor-ofのような形で、配列の要素の数だけ繰り返し描画して中の要素を扱うことができます。

<ul>
    <li v-for="member in memberList">{{ member }}</li>
</ul>
memberList: [
    '松井珠理奈', '須田亜香里', '宮脇咲良'
],

この場合では、 memberList の3回分 liタグを描画し、各要素の値を member という変数名で扱って表示しています。

そして下に表示されているテキストボックスに適当な名前を入力し、「リストに追加」ボタンをクリックすると

f:id:take7010:20180909175439p:plain f:id:take7010:20180909175448p:plain

リストに入力した名前が追加されます。
まず、HTML側で input タグに v-model というディレクティブを使っています。

<input v-model="name">
<button v-on:click="addMemberList">リストに追加</button>

この v-model で設定されたデータを、inputタグのvalueと連動させることができます。
この場合では

name: ''

ですね。
初期値は空文字を入れてあるので、テキストボックスも空になっています。
そして名前を入力すると name の値も同時に変更され、「リストに追加」ボタンをクリックした際に呼び出される addMemberList メソッドで、 memberList にその変更後の値が追加されます。

addMemberList: function() {
    this.memberList.push(this.name)
    this.name = ''
}

それと同時に、 memberList を呼び出していた li タグの要素も連動して更新されます。
最後に this.name = '' としているのは、リストへの追加後にテキストボックスを空の状態に戻すためです。
この行を消すとテキストボックスには入力した値がそのまま残るので、試してみてください。

テキストボックスを更新すると name の値が変わり、 name の値を更新するとテキストボックスの値が変わるので、「データを連動させる」という意味が分かるかと思います。

Vue.jsを触ってみて良かったこと

ということで思ったより長くなってしまったのですが、Vue.jsを触ってみた内容を紹介してみました。
本当はもうちょっと色々やったんですが、一旦は分かりやすい特徴のデータバインディングのことだけ。
あとは触ってみての感想を書こうと思います。

Webフロントへの抵抗感が薄れた

前述した通り、生のJavaScriptでDOMをゴリゴリいじるようなところでところで嫌いになって触ってなかったので、時代の進歩に感動しました笑
このレベルなら分かりやすいし、JavaのFreeMarkerとかサーバー側のテンプレートエンジンに近い感覚で扱える。
あとはロジックをJavaScriptで書くというだけなので。

今回はデータをコードにベタ書きで色々やりましたが、そこのデータをサーバーから取ってくる形にすれば、もう少し実用的になりそうですね。
最近流行りのFireBaseとかとの組み合わせで、たしかにサーバープログラム書かなくてもちょっとしたサービスなら作れそうです。
データ更新と取り出しができれば、あとはそれ使ってクライアント側でロジック書けるので。

並行してHTML、JavaScript、CSSの知識も少し付いた

基本的にVue.jsの情報は当然ながらWebフロントの基本的な部分は分かってる人向けに書いてあるので、浦島太郎には分からない要素もちょっとありました。
なんで今回紹介したようなサンプルコードを色々書いてるうちに、HTMLとかJavaScriptのことも色々調べたりして、それもまた勉強に。 あと今回は省きましたが、クラスとかスタイルを扱うこともできるので、CSSについても学びました。

序盤に「このレベル感で触っても分からないだろうと勝手に思い込み」JavaScriptのフレームワークとかを敬遠してきたと書きましたが、むしろこれを触ることで自然と必要に応じてベースの知識も覚えていくので良いのではないかと思いました。

リアクティブの概念がなんとなく理解できた

これは副次的な効果ですが。
お恥ずかしながら「リアクティブプログラミング」とかで「リアクティブ」いう言葉はよく聞くんですが、あまり理解していませんでした。
なのでVue.jsのデータバインディングのこととかを通して、そこについても体験するいい機会になりました。

最後に

ということでまだまだ触りだけですが、近代のWebフロントの世界に一歩踏み出せた気がして良かったです。
仕事で使う機会が来るか分かりませんが、せっかくなのでこれを使ってなにか作ってみようかと思います。