Edited at

【Vue・React・Elm】ビューの書き方を比べてみた


Vue.jsの場合



Vueのビューはこんな感じ

<template>

<div>
<button v-on:click="decrement">-1</button>
<div>{{ count }}</div>
<button v-on:click="increment">+1</button>
</div>
</template>

ほぼHTMLですね。見やすいです。



Vueでの条件分岐や繰り返し

v-ifv-forなどのディレクティブというものが用意されていて、それをHTMLの属性みたいに書きます。


【例】記事タイトル一覧

記事があれば、その分だけ繰り返し表示するし、1件もなければ「記事がありません。」と表示する例です。

<template>

<ul v-if="items.length">
<li v-for="item in items">
{{ item.title }}
</li>
</ul>
<p v-else>記事がありません。</p>
</template>

v-ifとかv-forとか色々覚えないといけませんが、個人的には割と分かりやすいと思います。



Reactの場合



Reactのビューはこんな感じ

render() {

return (
<div>
<button onClick={decrement}>-1</button>
<div>{ count }</div>
<button onClick={increment}>+1</button>
</div>
)
}

Babelというトランスパイラを使うことで、ReactのビューもHTMLみたいに書けます。

これはJSXという書き方なんですが、ほぼHTMLそのままで個人的には読みやすいと思します。

ちなみにJSX記法を使わない場合は、以下の様にReact.createElementメソッドを使用します。

render() {

return (
React.createElement('div', null,
React.createElement('button', { onClick: decrement }, '-1'),
React.createElement('div', null, count),
React.createElement('button', { onClick: increment }, '+1')
)
)
}



Reactでの条件分岐や繰り返し

JSXの中では、if文やfor文は使えません。

そのため三項演算子や配列のmapメソッドを使って記述します。


【例】記事タイトル一覧

render() {

return (
<div>
{ items.length > 0 ? (
<ul>
{ items.map((item) => {
return <li>{ item.title }</li>;
})}
</ul>
) : (
<p>記事がありません。</p>
)}
</div>
)
}

JSXの中でJavaScriptを書くときには波括弧で囲まなければいけません。



Elmの場合



賢い人は考えた

「HTML要素って、要はタグ名属性中に入ってる子要素たち・・・」

「この3つから構成されているやん?」

<div class="container" id="hoge">

<span>子要素</span>
</div>

「じゃあ、divとかspanっていう関数を作って・・・」

「第一引数には[ class "containor", id "hoge" ]みたいに属性のリストを渡して」

「第二引数には子要素のリストを渡せばええやん」

div [ class "container", id "hoge" ] [

span [] [ text "子要素" ]
]

「↑こう書いたらHTML要素を返してくれるような・・・」

「各タグ名に対応したHTML関数たちを作ればええんや!」

「ただの関数やから、ループさせるのに(v-ifとかv-forのような)専用の書き方とか要らんで」

「ElmのifList.map関数とかと、シームレスに組み合わせられるんや!」



Elmではdivspanすらも関数

Elmでは、各HTML要素に対応した関数があらかじめ用意されています。

(header, section, p 等々・・・)

このHTML関数たちを使って、ビュー部分プログラム部分をシームレスかつ柔軟に書くことができます。

「配列の分だけループして表示させるための特別な構文」もありませんし、

「属性値を動的に生成するための特別な書き方」もありません。



ということで、Elmのビューはこんな感じ

view model =

div []
[ button [ onClick Increment ] [ text "+1" ]
, div [] [ text <| String.fromInt model.count ]
, button [ onClick Decrement ] [ text "-1" ]
]



Elmでの条件分岐や繰り返し

条件分岐や繰り返しに関して、ビュー専用の構文はありません。

普通にElmのList.map関数とかifなどを使用します。


【例】記事タイトル一覧

view model =

div []
[ if List.length model.items > 0 then
ul [] (model.items |> List.map liComponent)
-- 記事(items)が1件以上あれば、
-- その分だけliComponentを呼び出して表示する

else
p [] [ text "記事がありません。" ]
]

-- ただ関数を作ればコンポーネントのように利用できる
liComponent title =
li [] [ text title ]



シンプルでいい感じ!