Javascriptのライブラリを漁る事に少しハマっています(笑)
軽量なもので何かいいのは無いか?と思って見つけたのが「Riot.js」です。何やらカスタムタグと言うのを用いて、コンポーネント化をしやすくする作りのようです。仮想DOMではないので、以前ちょっといじったUmbrella.jsも問題なく使えるようです。学習コストも少なめで、メンテナンスもしやすそうで、使い勝手もよさそうです。しかも、公式ページは、日本語ページもある!
というわけで、今回はこれでカウンターを作成してみようと思います。
Riot.jsの設置方法
Riot.jsはnpmもあるようですが、当方の環境はNode.jsないんで、今回も無難にCDN (htmlにURLを記述し、ネット経由で毎回読み込みに行く方法)で使いたいと思います。で、実際にhtmlに貼り付けるscriptタグは以下になります。
<!-- Riot.jp とコンパイラを含める、ver 9.1.4 (2024/03/27現在) --> <script src="https://unpkg.com/riot@9/riot+compiler.min.js"></script>
次に、index.htmlです。Riot.jsの現在のバージョンでは、作ったカスタムタグ(今回は「counter」 という名前のカスタムタグ)を別ファイルから読み込む形式(昔のバージョンの事はよくわかりません、すみません)のため、index.htmも特殊になります。以下、<body>タグ内の記述です。
<body>
<!-- ①「<カスタムタグ名 />」はここに別ファイルを読み込む形 -->>
<counter />
<!-- ②「<counter/>」 は外部ファイルで指定 -->
<script src="./counter.riot" type="riot"></script>
<!-- ③Riot.js とコンパイラを含める、ver 9.1.4 (2024/03/27現在) -->
<script src="https://unpkg.com/riot@9/riot+compiler.min.js"></script>
<!-- ④コンパイルとマウント -->
<script>
(async function main() {
await riot.compile()
riot.mount('counter')
}())
</script>
</body>①カスタムタグ設置場所
今回はカウンターを作るので、「counter」というカスタムタグを作ります。 別ファイルの読み込みになるので、設置場所の指定は、<counter></counter> ではなく <counter /> で行けるようです。
②.riotファイルの指定読込み
- 「src=”ファイル名.riot”」で別に作ったカスタムタグファイルの場所を指定
- 「type=”riot”」で type指定
以前のバージョンではこのtype指定が他の形だったようですが、現バージョンではこれでいけます。
③Riot.js とコンパイラをCDN
前述してますので割愛します。バージョンは9.1.4です。(2024/03/27現在)
④コンパイルとカスタムタグのマウント
このマウント方法も、以前バージョンよりもちょっと変わって、より複雑になっているようです。
尚、「riot.mount(‘counter’)」この部分は、第2引数にpropsの値も設定出来るようです。
riot.mount('カスタムタグ名') //この形から…
riot.mount('カスタムタグ名', propsの値) //第2引数にpropsを設定出来る
riot.mount('counter', { //今回はオブジェクトでtitleとverを設定
title: 'カウンター',
ver: `@ riot.js ${riot.version}`,
})第2引数のpropsには色々なものを設定出来るようですが、自分にはまだ難しいので、いずれ使いこなしていこうと思います。とりあえず今回は、オブジェクトでtitleとverを設定してみました。
- Riot.jsのバージョンは「consple.log(riot.version)」などで確認できます。
カスタムタグ(.riotファイル)作成
前述の通り、カスタムタグを扱うファイルを、index.html とは別に作っていきます。拡張子は「.riot」です。
<counter> // カスタムタグの中に必要コードの記述 ~~~ // html部 <style> ~~~ // CSS部 </style> <script> ~~~ // スクリプト部 </script> </counter>
カウンターの作成
では上記に基づき、カウンタ-を作っていこうと思います。目指す形は、次のようになります。
- +と-で数値の上下をさせる
- resetボタンを設置
- 数値の増減で、背景色が白から変化
- 値が正で赤系、負で青系に徐々に変化
簡単なものではありますが、練習にはちょうど良いと思います。
html部
<counter>
<p>{props.ver}</p> //①propsより値を取得
<h1>{props.title}</h1>
<div id="disp">
<h2 id="h2_d">{state.count}</h2>
<br>
<button onclick="{() => upDown(-1)}">-</button> //②onclick="{関数}"
<button onclick="{() => upDown(1)}">+</button> //③引付き関数
<button onclick="{reset}">reset</button> //③引数無し関数
</div>
<style>
{~~~}あまり説明個所がありません(笑)
- ①「{変数}」で変数表示
- ②「onclick=”{関数名}”」で、クリックイベント
- ③引数付き関数は 「{() => 関数(引数)}」
- ④引数無し関数は「{関数名}」
尚、コード内で変数の値が変わっても、それだけでは画面に適用されません。
後述する「this.upDated({})」をやって、初めて画面に再描画されます。
style部
<style>
#disp {
width: 6em;
}
#h2_d {
text-align: center;
width: 3em;
margin: 0 auto 0 auto;
}
</style>コード内に<style></style>を設けて、そこにスタイルを書くことが出来ます。公式の説明を読むと、CSSに関しては、独自のカスタム実装があるようです。:hostのような疑似クラスを用いた スコープ付きCSSとか興味あります。このカスタムタグ内でのみ動くCSSという感じなのでしょうか?
それはさておき、今回のカウンター作成においては、各要素の表示位置やwidthを定めるだけに留めています。カウンター背景色は、html要素内へのstyle書き込みで対応しています(後述)。
スクリプト部
<script>
export default { // exportは基本名前無しのdefaultで
onBeforeMount (props, state) {
// どこからでもアクセスできる変数「state」
this.state = {
count: 0, // stateはカウンターの数値表示用
};
},
onUpdated (props, state) {
// ページ更新の度に color()関数を実行
this.color(); // this を付けて関数設置
},
upDown (by) {
this.state.count += by;
// this.update({}) で該当要素の表示を更新
this.update({
"#h2_d" : this.state.count,
});
},
color () {
let hue = 255 - Math.abs(this.state.count) * 2;
let rgbColor =
this.state.count > 0 ? `rgb(255, ${hue}, ${hue})`:
this.state.count < 0 ? `rgb(${hue}, ${hue}, 255)`:
'rgb(255, 255, 255)';
this.$("#h2_d").style.backgroundColor = rgbColor;
},
reset () {
this.state.count = 0;
this.update({
h2_d: this.state.count,
});
// this.$("セレクター") で該当要素へアクセス
this.$("#h2_d").style.backgroundColor = 'rgb(255, 255, 255)';
// jQueryやUmbrellaでもやれる、以下はUmbrella
/* u("#h2_d").attr({style: 'backgroundColor: rgb(255, 255, 255)'}); */
},
}
</script>内容をまとめると
export
- exportは、基本名前無しのdefaultでやるようです。
変数宣言
- 「this.変数名」とするやり方と、関数のスコープ内では「constやlet」も使えるようです。
ライフサイクルコールバック
- ライフサイクルコールバック が使えます。今回使ったのは、
- onBeforeMount () {} コンポーネントがページにマウントされた直後
- onUpdated () {} updateでコンポーネントのテンプレートが更新された直後
関数内に他の関数呼び出し
- 「this.関数B」を関数Aの中に書くことで可能です。
this.update({})で画面の再描画
- 以下の様にオブジェクトで、複数の値を一気に再描画出来る。
this.update({
'セレクター1': 描画させたい変数1,
'セレクター2': 描画させたい変数2,
})DOM要素へのアクセス
- jQueryやUmbrellaのようなDOM要素アクセス
- this.$(‘セレクター’) 単発要素へアクセス
- this.$$(‘セレクター’) 複数要素へアクセス querySelectorAll()みたいな?
- 「this.$(“#h2_d”)」と「this.$(h2_d)」は同義っぽい?
thisってる多すぎ問題
- あっちもこっちもthis多すぎ(笑)
- this.$()でやるDOM操作は、jQueryやUmbrellaで代用してもいい
まとめ
Riot.js、案外使いやすいです。特にDOM操作に長けているjQueryやUmbrellaと併用できるのがいいですね。以前別のライブラリを試してみた時に、仮想DOM系のライブラリは、styleの適用に関して柔軟さに欠ける 感じがしたので、その点このRiot.jsはとてもよく出来ていると感じました。皆さんも興味を持ちましたら是非(笑)
今回参考にさせて頂いたサイト様
ありがとうございます。

コメント