まだまだ枠が大量に空いていたのでRiot.js Advent Calendar 2020に16日目の記事として参加します。また、なんか適当な Advent Calendar 202016日目にも参加します。
Riot公式のRouterであるRiot RouterのReadmeを2021年2月18日現在最新の版(432c94e)に基づき日本語訳しました。記事の内容は全てMITライセンスです。ライセンスの詳細は末尾に記載してあります。
2021/2/18更新: 2/13のコミット(432c94e)での更新を取り込み済みです。
Riot Router
Simple isomorphic router
The Riot.js Routerは以下の技術で実装されたミニマルなルーターです。
- DOM pushState や history API との互換性
- isomorphic functional API
- erre.js streams と javascript async generators
- rawth.jsのurls parsing
実行にはRiot.jsを必ずしも必要とせず、スタンドアローンモジュールとして利用できます。
Riot.js 3 以前のバージョンに関してはv3 branchを参照してください。
目次
インストール
2つのエディションがあります。
エディション | ファイル |
---|---|
UMD Version | route.js |
ESM Module | route.esm.js |
Standalone UMD Module | route.standalone.js |
Script injection
<script src="https://unpkg.com/@riotjs/route@x.x.x/route.js"></script>
注: x.x.x
の部分を利用したいバージョンに変えてください。 例: 4.5.0
、4.7.0
ESM module
import { route } from 'https://unpkg.com/@riotjs/route/route.esm.js'
npm
$ npm i -S @riotjs/route
自分でダウンロードする
ドキュメント
Riot.jsとの併用
以下のように <router>
コンポーネント と <route>
コンポーネント をインポートしてアプリケーション内で利用できます。
<app>
<router>
<!-- リンクは自動でHTML5 history eventsを発火する -->
<nav>
<a href="/home">Home</a>
<a href="/about">About</a>
<a href="/team/gianluca">Gianluca</a>
</nav>
<!-- アプリケーションルートがここにレンダリングされる -->
<route path="/home">
Home page
</route>
<route path="/about">
About
</route>
<route path="/team/:person">
Hello dear { route.params.person }
</route>
</router>
<script>
import { Router, Route } from '@riotjs/route'
export default {
components { Router, Route }
}
</script>
</app>
riot.register
メソッドを使用してグローバルに使用できるようにすることもできます。
import { Route, Router } from '@riotjs/route'
import { register } from 'riot'
// Routerコンポーネント と Routeコンポーネント がグローバルに有効になる
register('router', Router)
register('route', Route)
Router
<router>
コンポーネント はapplication markupで囲まれている必要があります。そうすることで、route eventのトリガーになるリンクの全てのクリックが自動的に検出されるようになります。
<router>
<!--riot router eventを発火 -->
<a href="/path/somewhere">Link</a>
</router>
<!-- 通常のリンクのようにrouter eventsを発火しない -->
<a href="/path/to/a/page">Link</a>
また、コンポーネント属性を通じてアプリケーションのbaseを定義することができます。
<router base="/internal/path">
<!-- base外のリンクのため通常のリンクのように機能する -->
<a href="/somewhere">Link<a>
</router>
ルーターコンポーネントはonStarted
コールバックも持ちます。 このコールバックは始めのroute eventが呼ばれた後に非同期的に呼ばれます。
<router onStarted={onRouterStarted}></router>
Route
<route>
コンポーネントは、子(単純なURLオブジェクト) にURLクエリパラメーターを検出できるようにするroute
プロパティーを提供します。
<route path="/:some/:route/:param">
{JSON.stringify(route.params)}
</route>
<route path="/search(.*)">
<!-- URLが"/search?q=awesome"であるように振る舞う -->
{route.searchParams.get('q')}
</route>
それぞれの <route>
コンポーネントはマウント、アンマウントされたときに知らせるために、自身のlifecycle属性を持ちます。
<app>
<router>
<route path="/home"
on-before-mount={onBeforeHomeMount}
on-mounted={onHomeMounted}
on-before-unmount={onBeforeHomeUnmount}
on-unmounted={onHomeUnmounted}
/>
</router>
</app>
スタンドアローン
このモジュールはriot.jsと共に使われるためだけではなく、スタンドアローンモジュールとして使われるようにも出来ています。Riot.jsのコンポーネントをインポートすることなくコアメソッドをexportして利用できます。これによって、あらゆる種類のフロントエンドシステムと互換性を持つルーターを構築してカスタマイズすることが可能です。
基礎
このモジュールはnodeとモダンブラウザ上で動き、rawthが公開しているrouter
(訳注: おそらくroute
)プロパティーとrouter
プロパティーをexportします。
import { route, router, setBase } from '@riotjs/route'
// 最初にbaseをセットする必要がある
setBase('/');
// root streamの作成
const aboutStream = route('/about')
aboutStream.on.value(url => {
console.log(url) // URL object
})
aboutStream.on.value(() => {
console.log('just log that the about route was triggered')
})
// 各route eventでトリガー
router.on.value(path => {
// この関数の中で path は常に文字列
console.log(path)
})
// route changeを手動でトリガー
router.push('/about')
// streamここまで
aboutStream.end()
Base path
ブラウザでルーターを使う前にapplication base pathを設定する必要があります。
これは単純にsetBase
で設定できます。
import { setBase } from '@riotjs/route'
// HTML5 history navigation を使用する場合
setBase(`/`)
// hash navigation を使用する場合
setBase(`#`)
application routeのbase pathは、ルートを作成する前の最初に必ず設定する必要があります。
DOM binding
上の例はブラウザ環境で動かしている場合、あまり実用的ではありません。ブラウザ環境ではルーターとroute change eventのトリガーとなる全てのDOM listening click eventに関連付けたいと思うはずです。
Window history popstate
eventsはルーターと接続する必要があります。
initDomListeners
メソッドは上の機能をすべて自動的にもたらします。
import { initDomListeners } from '@riotjs/route'
const unsubscribe = initDomListeners()
// page DOMとルーターを接続
// ...分解してルーターをDOMから切断
unsubscribe()
initDomListeners
はアプリケーション上のすべてのリンクのクリックを無効化します。しかし、特定のDOM領域だけを対象としてスコープするために、HTMLElementやHTMLElementのリストを引数として受け取ることができます。
import { initDomListeners } from '@riotjs/route'
initDomListeners(document.querySelector('.main-navigation'))
ライセンス
MIT License
Copyright (c) Gianluca Guarini
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.