理系学生日記

おまえはいつまで学生気分なのか

食わず嫌いだったVue.jsが結構おもしろかった

WebSocket を使う一環で React とか Vue.js とか流行りのヤツを調べたりしていたのですが、特に Vue.js がやたらおもしろいです。

コンポーネント

たとえばこれ、クソ簡単な文字カウンタのコンポーネントです。文字を入力すると、文字列そのものと文字数出すヤツ。

ソース

ソースはこんなかんじ。

<div id="component-demo">
  <char-number-counter></char-number-counter>
</div>
Vue.component('char-number-counter', {
    data: function() {
        return {
            chars: ''
        }
    },
    computed: {
        charCount: function () {
            return this.chars.length
        }
    },
    template: '<div>\
                 <label for="counter-input">入力文字列:</label>\
                 <input id="counter-input" v-model="chars" placeholder="edit me"></input>\
                 <p v-if="charCount > 0">"{{chars}}"{{ charCount }}文字です</p>\
               </div>',
})

new Vue({el: '#component-demo'})

で、もちろん自分でコンポーネントが作れるとか色々あるんですが、特に何がおもしろかったかというと。

双方向バインディング

双方向バインディングというのは、JavaScript -> DOM のみならず、DOM -> JavaScript の方向でもデータをバインドできるというものです。 上記の例だと、テキストボックスに入力した文字列が、そのまま JavaScript 側の変数としてバインドされます。 これが、v-model という attribute を付与するだけで良いっていうのが、まずぼくにとって革新的でした。

算出プロパティ

算出プロパティというのは、Vue.js が変更をトラックしているデータが更新されたときにだけ再評価されるプロパティです。 上記のソースには

    computed: {
        charCount: function () {
            return this.chars.length
        }
    },

という部分がありますが、ここで charCount プロパティ は this.chars に依存していることが分かるので、this.chars、つまりテキストボックスの中身が変更された 段階でこの変数は再評価され、キャッシュされます。

今回の例は、このキャッシュという観点でいうとあまり良くない例ですが、 入力が変更されたら外部 API 呼び出しが発生するようなケースにおいては、たいへん使い勝手が良い機能になりそうです。

JSX

さすがにコンポーネントが入り組んでくると、template や、仮想 DOM を createElement で書いていくのは厳しそうですが、 babel を使えば JSX でも書けるようです。

ちょっとこのあたりを含め触ってみたいなと思います。