🧊

噂のVue.jsをさわってみた

なんか流行りにのってる感があります。

参考:vue.js

なんかわからんけどはてブの上位に出てた、気象庁APIとあわせて使ってみました。

以下、サンプルのURLです。
ソース見た方がはやいかも。

気象庁APIの仕様変更?の影響か、レスポンスが取得できなくなったので、現在動作してません。

使用感なんて語れるほど大した身分ではないのですが、まあこういう風にも見えてるよ、ということでココはひとつ。

20140712追記
いまだぽつぽつブクマされるので追記です。
このサンプルで使ってるVue.jsはバージョンがかなり古いので、そこを念頭に置いた上で読んでください!
最近のバージョンアップでループまわりは記述方法変わってた気もするので。

さわるまえ

ドキュメントを読んでる感じ、Angular.jsの時と同じような印象。
「え、コードこんだけでいいの?うわ動いてるすげー!」っていう感じ。

コードのスタイルがシンプルなjsのオブジェクトで組んでいく風で、そこは使いやすそう。
(Angularの$scope祭りには戸惑った覚えがあるので)

ドキュメントもまだモリモリじゃないので、ちょっと頑張れば全部読める。

後は、このライブラリの恩恵を受け続けれるかどうかが気になって、

  • ディレクティブをどんだけ使いこなせるか(覚えられるか)
  • どこまでビルトインの仕組みを用意してもらえてるのか

みたいなことをチェックしたいですね。

Backboneは、よくも悪くもスーパーマンではなかったので、
いかに自分のコードを書かず、おいしいとこをいただけるかが気になるなと。
自分であれこれ作れる人からすると、また違った観点になるんでしょうかねー。

HTMLにガリガリあれこ書いていくスタイルがダメ!って人は、元からダメなんやろうなと思います。
まあそこはもう割切りな気もする今日このごろ。
時代の流れ的なものが見え隠れしてて、しっかりと見極められる目を養いたい!

さわってみて

実際のコードは後でメモるとして、ざっと。

  • モデルのバインディングっていうか、勝手に値が反映されるのはやっぱり楽でいい!
  • DOMがID祭りにならないのいい
  • v-show/v-if/とv-transitionのセットは中々ありがたい
  • v-ifはDOMから消えるけど、v-showはdisplay: none;ってだけの違いぽい
  • データ構造は生のjsです!っていうけど、実はgetter/setterだらけなのでconsoleでちょっと見にくい
  • 某ヒゲテンプレっぽく書ける風やけど、デリミタがヒゲなだけで {{#if}} とかはできない
  • なので、{{#each arr}} とかないから配列のネストの処理がわからない
  • Angularよりお手軽!ってどっかで見たけど、ちゃんとしてる分だけやはり学習コストはかかる
  • ドキュメントはあるけど、まだまだ生きたサンプルが少ない(ってか、ない)
  • Backboneとは住む世界が違う気がする(機能としてはRoutingとかもないし、そもそも比較対象なん?)
  • あとはパフォーマンスが気になる(特にモバイル)

当然ですが、もうちょっと使ってみないと、実戦投入できるかは測りかねる感じ。
そもそもまだv0.8.6(20140219現在)やし。

コードのメモ

そのまんまです。

<section id="demo">
  <div class="input">
    <h1>{{title}}</h1>
    <input type="text" v-model="forms.title" /><input type="date" v-model="forms.date">の日中のデータから<br>
    <input type="number" v-model="forms.limit"><label><input type="radio" name="order" value="new" v-model="forms.order">新しい</label>
    <label><input type="radio" name="order" value="old" v-model="forms.order">古い</label>順に
    <button v-on="click: search">検索!</button>
    <button v-on="click: clear">削除!</button>
    パラメータ: order={{forms.order}}&limit={{forms.limit}}&datetime={{forms.date}} 00:00:00&datetime={{forms.date}} 23:59:59&title={{forms.title}}
  </div>

  <!-- ここにデータいれる -->
  <div>{{> repeat}}</div>
</section>

<!-- テンプレ -->
<script type="text/v-template" id="repeat-tmpl">
  <article class="no-data" v-show="!results.length" v-transition>まだデータがないよ</article>
  <article v-repeat="results" v-on="click: tweet" class="article-{{$index}}">
    <header>
      [{{datetime}}] <a href="{{link}}" target="_blank">詳細(XML)</a>
      <h2>{{title}}</h2>
    </header>
    <p>{{headline | getFirst}}</p>
    <!-- <p>{{#each headline}}{{this}} / {{/each}}</p> <- NOT WORK... -->
  </article>
</script>
  • {{hoge}}でデータはバインディング
  • input類みたく値をいじれるやつはv-modelで連携できる
  • v-onでイベント貼れる
  • v-show/v-ifで特定のデータのT/Fで挙動かえれる
  • v-repeatで繰り返し

ってだけでだいぶいろいろやれるぽい。

// 独自のフィルタは大元に。
Vue.filter('getFirst', function (value) {
  if (!value) { return; }
  if (typeof value !== typeof []) { return; }
  return value[0];
});

var demo = new Vue({
  el: '#demo',
  // 部品テンプレつかえる
  partials: {
    repeat: '#repeat-tmpl'
  },
  data: {
    title: '気象庁防災情報 XML 検索 APIから、その日中の気象警報・注意報を検索!',
    // input[type:hoge]に紐付けてるモデルたち
    forms: {
      title: '気象警報・注意報',
      date: '2014-01-01',
      order: 'new',
      limit: 5
    },
    // 主たるデータ
    results: []
  },
  methods: {
    search: function() {
      // いわんやdataです
      var $data = this.$data;
      var $forms = $data.forms;
      var base = 'http://api.aitc.jp/jmardb/search';
      var param = [
        'order=' + $forms.order,
        'limit=' + $forms.limit,
        'datetime=' + $forms.date + ' 00:00:00',
        'datetime=' + $forms.date + ' 23:59:59',
        'title=' + $forms.title
      ];
      $.ajax({
        url: base + '?' + param.join('&')
      }).done(function(data){
        // setとかreplaceとかしなくても、これでもViewは更新される
        $data.results = data.data;
      });
    },
    tweet: function(e) {
      console.log(this); // コレはこのdemoVMのこと
      console.log(e.targetVM); // コレは今クリックされたrepeatされてるVM
      global.alert(e.targetVM.headline[0]);
    },
    clear: function() {
      this.$data.results = [];
  }
});
  • カスタム○○は勝手に定義する
  • elでDOMと一緒にVMは初期化する
  • バインドしたいデータはdata以下
  • メソッドはmethods以下

もはや説明しなくてもコード見ればわかる、ってすごいことですね。

わからなかったこと

  • v-repeatでまわす配列の中に、さらに配列がいる場合にどうやるんか

上記の例で、ajaxで取得してるdata.data[n].headlineは配列なのですが、それをどうやってイテレーションすればいいのかわかりませんでした。
わからんので今回は無理やりフィルターを試すということにしました・・。

最近のバージョンでできるようになったぽい!きたこれ!
Vue.jsでv-repeatをネストするには - console.lealog();

さいごにメモ

まさかのご本人様の登場でした。

v-repeatで配列まわすときで、突っ込むデータがその配列だけな場合の話かな。
mentionやけど答えにはなってないw

new Vue({
  el: '#tags',
  data: {
    tags: ['JavaScript', 'MVVM', 'Vue.js']
  }
});

で、

<ul id="tags">
  <!--<li v-repeat="tags">{{value}}</li>-->
  <li v-repeat="tags">{{$value}}</li>
</ul>

ってことかな?

めもめも。
というように、これからもアップデートが頻繁にくる感じですね!期待してます。

参考:vuejs

RouterとかTouchとかあるー!
また今度試してみようー。