Riot 2.0を試してみる（Custom tags編

https://muut.com/riotjs/guide/
[前回](http://qiita.com/kazusa-qooq/items/e1f3ca2990b3aed0e300)、Riotのコンパイル方法を学びました。では、ようやく、カスタムタグの作成にはいりましょう。今回はカスタムタグの全体像を把握できればと思います。
jsFiddle上でやりたかったのですが、うまくいかなかったのでcloud9で試します。
やりながら書いているので間違い等あればご指摘頂ければ幸いです。


#Custom tag example
まず例を表示することから始めたいと思います。カスタムタグを使用するindex.htmlと、カスタムタグが書かれたtodo.tagを同じフォルダに用意します。

``` index.html
<body>

  <!-- place the custom tag anywhere inside the body -->
  <todo></todo>

  <!-- include riot.js -->
  <script src="https://cdn.jsdelivr.net/g/riot@2.0(riot.min.js+compiler.min.js)"></script>

  <!-- include the tag -->
  <script src="todo.tag" type="riot/tag"></script>

  <!-- mount the tag -->
  <script>
    riot.mount('todo', { 
      title: 'My TODO app', 
      items: [ 
        { done: false, title:"Hallo Riot" }
      ] 
    })
  </script>

</body>
```

``` todo.tag
<todo>
  <style>
    label.completed { text-decoration: line-through; }
  </style>

  <h3>{ opts.title }</h3>

  <ul>
    <li each={ items }>
      <label class={ completed: done }>
        <input type="checkbox" checked={ done } onclick={ parent.toggle }> { title }
      </label>
    </li>
  </ul>

  <form onsubmit={ add }>
    <input name="input" onkeyup={ edit }>
    <button disabled={ !text }>Add #{ items.length + 1 }</button>
  </form>

  this.disabled = true

  this.items = opts.items

  edit(e) {
    this.text = e.target.value
  }

  add(e) {
    if (this.text) {
      this.items.push({ title: this.text })
      this.text = this.input.value = ''
    }
  }

  toggle(e) {
    var item = e.item
    item.done = !item.done
    return true
  }

</todo>
```

サーバーを立ち上げて画面を見てみましょう。cloud9上ならindex.htmlを開いてRunボタンを押せば起動できます。次のような画面がでれば成功です。

![image](https://qiita-image-store.s3.amazonaws.com/0/71988/e484e463-3d03-e1fe-792c-7bbab13f2bae.png)


##Tag syntax
ではRiotの仕組みについて見ていきます。Riotのタグはレイアウト（HTML)とロジック（JavaScript)の組み合わせです。以下に基本ルールを示します。

* レイアウトとしてHTMLが先に定義され、その後にロジックをscriptタグに記述します
* レイアウトの記述が終了した後ならscriptタグなしでロジックが書けます。これはオープンシンタックスと呼ばれ、よりスマートです。
* カスタムタグは空でもいいし、レイアウトだけでもいいしロジックだけでもいいです。
* クォートは自動補完されます。`<foo bar={ baz }>` -> `<foo bar="{ baz }">`
* ES6のメソッド表記をサポートしています。`methodName()` -> `this.methodName = function()`
* thisは常にカスタムタグのインスタンスを指します
* class名用にショートカットが用意されています。`class={ completed: done }`はdoneがtrueの時、`class="completed"`になります
* 同様にchecked, selected などのBoolean属性は`checked={ flag }`のように記述できます。
* 属性名は小文字でなければなりません
* カスタムタグは閉じる必要があります
* タグ定義は行頭から始まる必要があります。タブや空白の後に記載してはいけません。

以上のルールでtodo.tagの中身がだいたい把握できると思います。

##Tag styling
`<style>`タグはRiotにより検出されheadタグに自動的に移動されます。例ではチェックすると打消し線が表示されるスタイルを定義しています。

``` todo.tag
<todo>
  <style>
    label.completed { text-decoration: line-through; }
  </style>
・・・
</todo>
```

![image](https://qiita-image-store.s3.amazonaws.com/0/71988/e2c23299-a954-ecbc-92f8-f0a6648a955e.png)

##Mounting
次にカスタムタグを使用しているindex.htmlで何をしているか見ていきましょう。

* カスタムタグは`<todo></todo>`のように使用します。`<todo/>はサポートされてません。
* カスタムタグは`riot.mount()`の呼び出しにより、タグ`<todo></todo>`にその実装がマウントされます
* マウント時、オプションを渡すことができます
* 渡されたオプションはカスタムタグ側で変数`opts`のフィールドしてアクセスできます

``` index.html
<body>

  <!-- place the custom tag anywhere inside the body -->
  <todo></todo>
・・・
  <!-- mount the tag -->
  <script>
    riot.mount('todo', { 
      title: 'My TODO app', 
      items: [ 
        { done: false, title:"Hallo Riot" }
      ] 
    })
  </script>

</body>
```

``` todo.tag
・・・
<h3>{ opts.title }</h3>
・・・
```

以上の内容でindex.htmlが行っていることがだいたいわかると思います。

##Tag lifecycle
今回の最後にタグのライフサイクルとイベントの発行タイミングについて学びましょう。

1. タグを構築
2. ロジックを実行
3. HTML Expression `{~}`を解決し、updateイベントを発行
4. タグをページにマウントし、mountイベントを発行
5. タグが取り除かれる際に、unmountイベントを発行

updateイベントの発行タイミング

* イベントハンドラ呼出し後
* this.update()が呼び出された時
* 親要素でthis.update()が呼び出された時
* riot.update()が呼び出された時。これはページ全体をアップデートする際に呼び出されます。

 
今回は実際にRiotのカスタムタグを動かし、その全体像を見てきました。
とりあえずカスタムタグは基本的にレイアウトとロジックのペアだということ、使用する際にマウントする必要があることがわかれば十分でしょうか。
次回はより詳細にカスタムタグの作り方を見ていく予定です。
[次回](http://qiita.com/kazusa-qooq/items/e8194297b4e7af415a7a)