【Riot.js】でカウンター作成。カスタムタグ要する異端のJavaScriptライブラリの使い勝手は?

run-riotの画像 JavaScript
フリーイラスト:Pixabay

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はとてもよく出来ていると感じました。皆さんも興味を持ちましたら是非(笑)

今回参考にさせて頂いたサイト様

ありがとうございます。

コメント

タイトルとURLをコピーしました