Riot.js V4系であえてロケーションハッシュ(#xxx)でルーティングをする

今年もアドベントカレンダーの季節がやってきました！！！ヽ(=´▽`=)ﾉ
弊社[デジクエ](https://qiita.com/advent-calendar/2020/digiq-tech)のカレンダー初日を担当させて頂きます、リードエンジニアの大野です。よろしくお願いしますm(_ _)m

# `Riot.js` V4系であえてロケーションハッシュ(#xxx)でルーティングをする

弊社では私の好みも多分に含まれますが`Riot.js`を使った`SPA`を作ることが多いです。
最近では`SSR`等も流行なようなので`SSR`で昔ながらの 「/(スラッシュ)」によるディレクティブなルーティングをする`SPA`が増えていますね。

`Riot4`系のルーターも標準では「/(スラッシュ)」によるルーティングになっているようです。
しかしそんな中ではありますが、あえてディレクティブなものでなく「#(ハッシュ)」を使ったルーティングを設定して見たので、「#(ハッシュ)」派の人は是非ご参考下さい！m(_ _)m

**※管理ツールなどで特に`SSR`を必要しない要件で、さっくり`SPA`したい派の方特に必見です！**

## STEP1. Roit4系のルーターの読み込み

標準？で提供されているコチラをまずルーターとして使います。
[https://github.com/riot/route](https://github.com/riot/route)

```html
<!DOCTYPE html>
<html>
  <head lang="ja">
    <meta charset="UTF-8">
    <title>Riotルーターサンプル</title>
  </head>
  <body>
    <h1>Riot4ルーターサンプル</h1>
  </body>
    <!-- riot4本体 -->
    <script src="//unpkg.com/riot@4/riot+compiler.min.js"></script>
    <!-- Riot4用のルーター -->
    <script src="//unpkg.com/@riotjs/route@4.0.0-beta.1/route.js"></script>
</html>
```

シンプルにベースはこんな感じです。

## STEP2. シンプルなHello worldサンプル

先ずは、シンプルに2ページを行き来するサンプルを用意

```html
<!DOCTYPE html>
<html>
  <head lang="ja">
    <meta charset="UTF-8">
    <title>Riotルーターサンプル</title>
  </head>
  <body>
    <h1>Riot4ルーターサンプル</h1>
    <ul>
      <li><a href="./">トップ</a></li>
      <li><a href="./sample">サンプル</a></li>
    </ul>
    <app></app>
  </body>
  <!-- riot4本体 -->
  <script src="//unpkg.com/riot@4/riot+compiler.min.js"></script>
  <!-- Riot4用のルーター -->
  <script src="//unpkg.com/@riotjs/route@7.0.0/route.js"></script>

  <!-- appタグをインライン定義 -->
  <template id="app">
    <app>
      <router>
        <route path="{window.location.pathname}">
          <h2>Hello world!</h2>
        </route>
        <route path="{window.location.pathname}sample">
          <h2>サンプル！</h2>
        </route>
      </router>
    </app>
  </template>

  <script>
    // appタグを読み込み
    riot.inject(riot.compileFromString(document.getElementById('app').innerHTML).code, 'app', './app.html');
    // riotをコンパイル
    riot.compile().then(() => {
      riot.register('route', route.Route);
      riot.register('router', route.Router);
      // ルートディレクトリ外でも動くようにベースパスを設定
      route.setBase(`${window.protocol}//${window.host}${window.location.pathname}`);
      riot.mount('app');
    });
  </script>
</html>
```

ブラウザで実行したサンプルは以下
![スクリーンショット 2020-11-26 17.20.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151630/cf9af551-96fe-0096-91cc-71273055062e.png)
[http://plnkr.co/plunk/IogODWhBcSlmVAzw](http://plnkr.co/plunk/IogODWhBcSlmVAzw)

ルーターを入れた基本はこんな感じになってます。
サンプルを実際にローカルで実行してみるとわかると思いますが、デフォルトではルーターは「/(スラッシュ)」によるディレクティブなルーターになっていると思います。
本来はこれで十分に満足出来るんじゃないでしょうか。

これを「#(ハッシュ)」ベースのルーターに変えるんですが、実は凄く簡単です。

## STEP3. 「#(ハッシュ)」ベースのルーターに変えたサンプル

実はものすごく簡単で

```javascript
route.setBase(`${window.protocol}//${window.host}${window.location.pathname}`);
```

の行を#を含めた形に変えて上げて

```javascript
route.setBase(`${window.protocol}//${window.host}${window.location.pathname}#`);
```

後はリンクとpathを#式に変えてあげるだけでOKです。

実際の書き換えた後のサンプルは以下

```html
<!DOCTYPE html>
<html>
  <head lang="ja">
    <meta charset="UTF-8">
    <title>Riotルーターサンプル</title>
  </head>
  <body>
    <h1>Riot4ルーターサンプル</h1>
    <ul>
      <li><a href="#">トップ</a></li>
      <li><a href="#sample">サンプル</a></li>
    </ul>
    <app></app>
  </body>
  <!-- riot4本体 -->
  <script src="//unpkg.com/riot@4/riot+compiler.min.js"></script>
  <!-- Riot4用のルーター -->
  <script src="//unpkg.com/@riotjs/route@7.0.0/route.js"></script>

  <!-- appタグをインライン定義 -->
  <template id="app">
    <app>
      <router>
        <route path="{window.location.pathname}">
          <h2>Hello world!</h2>
        </route>
        <route path="{window.location.pathname}#sample">
          <h2>サンプル！</h2>
        </route>
      </router>
    </app>
  </template>

  <script>
    // appタグを読み込み
    riot.inject(riot.compileFromString(document.getElementById('app').innerHTML).code, 'app', './app.html');
    // riotをコンパイル
    riot.compile().then(() => {
      riot.register('route', route.Route);
      riot.register('router', route.Router);
      // ルートディレクトリ外でも動くようにベースパスを設定
      route.setBase(`${window.protocol}//${window.host}${window.location.pathname}#`);
      riot.mount('app');
    });
  </script>
</html>
```

ブラウザでの実行結果は以下
![スクリーンショット 2020-11-26 19.03.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151630/0d604da1-96b4-b2b1-f063-759db041bdcf.png)
[http://plnkr.co/plunk/veYITpKjBuVEc91A](http://plnkr.co/plunk/veYITpKjBuVEc91A)

こんな感じで非常に簡単に「#(ハッシュ)」ベースに変えられました！

# まとめ

「#(ハッシュ)」ベースのルーターの場合のいいところは`SSR`と逆行しますがサーバーサイドの設定などは特に不要になる点かなと思います。
管理ツールだったり、非公開のアプリケーションであったりの場合は特に`SSR`に絶対にしないとならないシチュエーションでは無く、サックリ`SPA`が作れればいい！と言うことも多々あると思ってます。
(特に`Riot`はブラウザコンパイル出来てとてもサクッと`SPA`出来るので尚更)
そう言う時のTIPSとして是非ご参考下さいm(_ _)m