Riot.jsで作った消費税計算ツールとRiot v3の好きな所
Tag:JavaScriptWeb
これはRiot.js Advent Calendar 2019の4日目の記事です。
Riot.jsもVue.jsがGitHubスター1万程の時は同じぐらいの知名度だったと思いますが、今では大きく差をつけられアドベントカレンダーも空きが目立つので(涙)、少しでも布教になればと書かせてもらいました。
しかしながら僕が好きなのはv3時代のRiotです。
最新版はv4ですが、v4になって制約が多くなりriot特有のメリットが薄れたと思うのでv3のまま使っています。
制作物
Riot.jsはツール的なもの作る時とても便利ですね。
v3でriotを使いたい時の参考にして下さい。
cssは無視しています。
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!doctype html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>tax</title> <script src="riot+compiler.min.js"></script> <script type="riot/tag" src="tag.html"></script> </head> <body> <div data-is="riot-main"></div> <script> riot.settings.autoUpdate = false; riot.compile(function(){ riot.mount('*'); }); </script> </body> </html> |
tag.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
<riot-main> <div class="theme_light"> <div class="re_container st_form_light re_pv_5"> <div data-is="riot-calc" mode="in"></div> <div data-is="riot-calc" mode="out"></div> </div> </div> </riot-main> <riot-calc> <div class="re_row_2 re_pv_5"> <div class="re_col_lg_3"> <div><span class="title3">税抜</span></div> <div><input class="st_form_input" type="text" readonly="{mode==='out'}" onkeyup="{ehTypeIn}" ref="input_out"/></div> </div> <div class="re_col_lg_3"> <div><span class="title3">税</span></div> <div><input class="st_form_input" type="text" readonly ref="input_tax"/></div> </div> <div class="re_col_lg_3 re_pb_4"> <div><span class="title3">税込</span></div> <div><input class="st_form_input" type="text" readonly="{mode==='in'}" onkeyup="{ehTypeOut}" ref="input_in"/></div> </div> <div class="re_col_lg_3"> <div> <div class="st_form_group"> <span class="st_form_addon">税</span> <select class="st_form_input" onchange="{ehChangTax}"> <option each="{val in optionListTax}" value="{val}" selected="{val===optionTax}">{val}%</option> </select> </div> </div> <div class="re_pt_1"> <div class="st_form_group"> <span class="st_form_addon">端数</span> <select class="st_form_input" onchange="{ehChangPoint}"> <option each="{val in optionListPoint}" value="{val}" selected="{val===optionPoint}">{val}</option> </select> </div> </div> </div> </div> <script> var tag = this; tag.mode = tag.opts.mode; tag.optionListTax = ['3', '5', '8', '10']; tag.optionListPoint = ['切り捨て', '切り上げ', '四捨五入', 'そのまま']; tag.optionTax = tag.optionListTax[2]; tag.optionPoint = tag.mode==='in' ? tag.optionListPoint[0] : tag.optionListPoint[1]; tag.ehTypeIn = function(e){ tag.refs.input_out.value = e.target.value.replace(/[^0-9.]/g, ''); inputUpdate(); }; tag.ehTypeOut = function(e){ tag.refs.input_in.value = e.target.value.replace(/[^0-9.]/g, ''); inputUpdate(); }; tag.ehChangTax = function(e){ tag.optionTax = e.target.value; inputUpdate(); // tag.update(); }; tag.ehChangPoint = function(e){ tag.optionPoint = e.target.value; inputUpdate(); // tag.update(); }; function inputUpdate(){ var val, tax; //税込を求める if(tag.mode==='in'){ if(tag.refs.input_out.value==='') return; val = tag.refs.input_out.value; tax = val * tag.optionTax / 100; if(tag.optionPoint==='切り捨て'){tag.refs.input_tax.value = Math.floor(tax);} if(tag.optionPoint==='切り上げ'){tag.refs.input_tax.value = Math.ceil(tax);} if(tag.optionPoint==='四捨五入'){tag.refs.input_tax.value = Math.round(tax);} if(tag.optionPoint==='そのまま'){tag.refs.input_tax.value = tax;} tag.refs.input_in.value = tag.refs.input_out.value * 1 + tag.refs.input_tax.value * 1; } //税抜を求める if(tag.mode==='out'){ if(tag.refs.input_in.value==='') return; val = tag.refs.input_in.value; tax = tag.refs.input_in.value - val / (1 + tag.optionTax / 100); if(tag.optionPoint==='切り捨て'){tag.refs.input_tax.value = Math.floor(tax);} if(tag.optionPoint==='切り上げ'){tag.refs.input_tax.value = Math.ceil(tax);} if(tag.optionPoint==='四捨五入'){tag.refs.input_tax.value = Math.round(tax);} if(tag.optionPoint==='そのまま'){tag.refs.input_tax.value = tax;} tag.refs.input_out.value = tag.refs.input_in.value - tag.refs.input_tax.value; } } </script> </riot-calc> |
Riot v3 こうすると使いやすい
Riot.js v3は自由に書けるのですが使っていく内にある程度ルールを定めて使った方が使いやすくなりました。
そうとう意識の低いルールになっていますが、とてもコードを書くのが楽しいです。
上記のコードも基本的にこの規則に従っています。
1. settings.autoUpdateをfalseにして自動でタグが更新されないようにする
理由:自動でupdateするとパフォーマンスが悪いので手動でupdateするようにします。
2. タグ内でまずlet tag = this;と定義してインスタンスをtagという変数で扱う
理由:thisだと呼び出し元によって対象が変わるため
3. onclickなどのイベントにバインドする関数(イベントハンドラ)の名前はehではじめる
理由:どの関数がイベントハンドラ用か、わからなくなるから
4. riot-mainというカスタムタグを作り、その中でほかのカスタムタグを読み込み、ifディレクティブで調整する
理由:最初のみmountメソッドを使えば、以降はデータに応じで自動でmount, unmountしてくれる
5. tagファイルの拡張子を.htmlにする
理由:エディタでhtml, js, cssのシンタックスハイライトがきちんと動作する
6. 1アプリケーション1ファイルで複数のタグをまとめて書く
理由:処理を探すのが楽
7. タグの事前コンパイルはせずにブラウザでコンパイルする
理由:ビルドツールが不要なので気軽に書ける
8. タグ名はriot-で始める
理由:Riotによって作成されたタグだとわかりやすい
9. タグはdata-is属性でマウントする
理由:spanやliやtdなどで使えるので意図したレイアウトにしやすい
他にも作ってます
他にも各種サービス・ツールをRiot.jsを使って作っています。
ウェブゴトのサービス
RIOT! RIOT! RIOT!