[phiary] とりあえず試してみたいって方のための Riot.js 入門

**※本家はこちらの[ブログエントリー](http://phiary.me/riotjs-tutorial-try/)になります.**
**毎日 html, css, js についてのエントリーを公開しているのでよかったら[RSS登録](http://feedly.com/i/subscription/feed/http://phiary.me/feed)してください♪**






![riot.js](https://www.evernote.com/l/AOJbE-0PaoxKYYJ9HjVXf3SoO4u_Z1luWvwB/image.png)

先日書いた 『[Electron の入門エントリー](http://phiary.me/electron-tutorial-try/)』 が好評だったので私の大好きな [Riot.js](http://riotjs.com/ja/) の入門も書いてみました.

AngularJS や React でもいくつか Web アプリケーション作ってきましたが,
私にとっては Riot.js が一番しっくりきました. 

なので今回は Riot.js について紹介します.
とにかく詳しい説明はいいから触って試してみたいって方はぜひ読んでみてください.

[Runstant](http://runstant.com) を使って作ったデモを並べているので, 実際に動かしたりコードをいじることができます.
実際に動かしながら, Riot.js がどれだけ使いやすいか体感してみてください♪

<div id='toc'></div>


## Riot.js とは？

今のところ私にとって(使いやすさ, 手軽さ, 規模感総合して)最も優れた JavaScript フレームワークです.

### 主な特徴

個人的に Riot.js でいくつかサービス作ってきての印象です.

- コンポーネント指向(これが一番刺さった)
- もちろん Virtual DOM
- ランタイムでコンパイル実行できる
- プリプロセッサもいけるし, Jade や coffee なんかも使える
- DOM に余計なことしないので他のライブラリとの親和性が高い
- ライブラリ自体のサイズが小さい
- updates, reflows のタイミングが直感的かつコントロールしやすい

### Reference

- [Riot.js — A React-like user interface micro-library · Riot.js](http://riotjs.com/ja/)
- [riot/riot](https://github.com/riot/riot)
- [riot/riot - Gitter](https://gitter.im/riot/riot)

## Getting Started

view タブをクリックしてみてください.
最もシンプルなデモで, Riot.js を使った最小限の構成です.
これをベースにサンプルを展開していきます.

### Demo

[runstant](http://runstant.com/phi/projects/riot-template)

### Code

```html
<!doctype html>
 
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    
    <title>${title}</title>
    <meta name="description" content="${description}" />
    <script src='https://cdnjs.cloudflare.com/ajax/libs/riot/2.3.18/riot+compiler.js'></script>
    
    <style>${style}</style>
  </head>
  <body>
    <!-- ユーザー定義のタグをここに展開 -->
    <app title='Hello, Riot.js'></app>

    <!-- app タグを定義 -->
    <script type="riot/tag">
      <app>
        <h1>{ title }</h1>
        this.title = opts.title;
      </app>
    </script>
    
    <script>
      // マウント
      riot.mount('*');
    </script>
  </body>
</html>
```

以降, html タグ部分は変わらないので Riot.js に関する部分のみ紹介していきます.

### Description

- `riot+compiler.min.js` 読み込む
- `script` タグのタイプに `riot/tag` を指定して `app` タグを定義
- body に定義した `app` タグを設置
- `riot.mount('*')` で展開
- attribute の title の値が `opts` として渡ってきて `app` タグの `h1` 内に展開

## Expressions

式の評価です.
`{ ... }` の中で色々できます.

### Demo

[runstant](http://runstant.com/phi/projects/75fea826)


### Code

```html
<script type='riot/tag'>
  <app>
    <h1>expressions</h1>
    <ul>
      <li>{ name }</li>
      <li>{ title || "タイトルないよー" }</li>
      <li>{ flag ? 'ready' : 'loading' }</li>
      <li>{ new Date() }</li>
      <li>{ Math.round(64.5) }</li>
    </ul>
    
    this.name = 'phi';
    this.flag = false;
  </app>
</script>
```

### Description

- 変数を展開したり
- デフォルト値設定したり
- 三項演算子使ったり
- 日付表示したり
- 括弧内で計算したり
- Math の関数使ったり
- 真偽値で class 属性を制御したり

## Loops

each 属性に指定するだけで展開してくれます.

### Demo

list の内容が展開されているのが分かるかと思います.

[runstant](http://runstant.com/phi/projects/6891365d)


### Code

```html
<script type='riot/tag'>
  <app>
    <h1>expressions</h1>
    <ul>
      <li each='{list}' class='{done:done}'>{ title }</li>
    </ul>
    
    <style>
      li.done {
        color: #aaa;
        text-decoration: line-through;
      }
    </style>
    
    this.list = [
      {
        title: 'Hello, world!',
        done: false,
      },
      {
        title: '牛乳を買う',
        done: true,
      },
      {
        title: '豚肉を買う',
        done: false,
      },
    ];
  </app>
</script>
```

### Description

- each 属性に配列を指定する
- 展開される

## Event handlers

イベントのバインドも簡単♪

### Demo

[runstant](http://runstant.com/phi/projects/d35a3e01)

### Code

```html
<script type='riot/tag'>
  <app>
    <h1>Event handlers</h1>
    
    <button onclick='{click}'>click</button>
    
    <ul>
      <li each='{list}'>
        <button onclick='{clickItem}'>{name}</button>
      </li>
    </ul>
    
    this.list = [
      {name:'hoge'},
      {name:'foo'},
      {name:'bar'},
    ];
    
    this.click = function() {
      console.log('click されたよー');
    };
    
    this.clickItem = function(e) {
      console.log(e.item.name + 'が click されたよー');
    };
  </app>
</script>
```

### Description

- onclick イベントに `{}` を挟んでイベント関数を登録
- クリックすると登録された関数が実行される
- each で展開したやつにアクセスする場合は `e.item`

## Form

フォームのサンプルです.
name 属性に値を指定しているとその値でアクセスできます.

### Demo

[runstant](http://runstant.com/phi/projects/68a98125)

### Code

```html
<script type='riot/tag'>
  <app>
    <h1>form</h1>
    
    <form onsubmit='{submit}'>
      <input type='text' name='username' />
      <input type='password' name='password' />
      <button type='submit' name='submit'>login</button>
    </form>
    
    this.on('mount', function() {
      this.username.value = 'phi';
      this.password.value = '1234abcd';
    });
    
    this.submit = function() {
      console.log('username: ', this.username.value);
      console.log('password: ', this.password.value);
    };
  </app>
</script>
```

### Description

- `form` の `onsubmit` に `submit` 関数を登録
- `input` の `name` 属性にそれぞれ `username`, `password` を指定
- mount 時にデフォルト値を設定
- login ボタンを押すと `submit` 関数が実行される
- console に username, password それぞれの値が表示される

## if/show/hide

### Demo

[runstant](http://runstant.com/phi/projects/4fcd581e)

### Code

```html
<script type='riot/tag'>
  <app>
    <h1>if/show/hide</h1>
    
    <button onclick='{toggle}'>click</button>
    <div if='{visible}'> look </div>
    <div show='{visible}'> show </div>
    <div hide='{visible}'> hide </div>
    
    this.visible = true;
    this.toggle = function() {
      this.visible = !this.visible;
    };
  </app>
</script>
```

### Description

- if ... true:存在 / false:削除
- show ... ture: `display:''` / false: `display:none`
- hide ... ture: `display:none` / false: `display:''`

<!--
## Mixin

-->

## Scoped CSS

Scope で閉じた CSS を指定できます!

### Demo

下の h1 タグしか色が変わってないのが分かるかと思います.

[runstant](http://runstant.com/phi/projects/4716a211)

### Code

```html
<script type='riot/tag'>
  <app>
    <h1>{ title }</h1>
    <style scoped>
      :scope h1 {
        color: red;
      }
    </style>
    this.title = opts.title;
  </app>
</script>
```

### Description

- `style` タグに `scoped` 属性を付ける
- `:scope query { ... }` という形でスタイル指定


Riot.js 便利ですよ♪
ぜひ使ってみてください:D