本記事は Riot.js Advent Calendar 2019 の第22日目です.
以下, 注意事項です.
-
Riot.js を
riot
と呼ぶ -
@riotjs/route を
route
と呼ぶ - 本記事の route は
v5.2.0(執筆時点の最新)
とする
※v5 については別途記事を書き中
onBeforeRoute
イベントハンドラの生成
route のソースコードを見ていくと, 2つ riot コンポーネントが見つかりますが, その中の route-hoc.riot を見てみますと,
onBeforeRoute(path, pathToRegexp) {
if (!match(path, this.state.pathToRegexp)) {
this.update({
route: null
})
}
},
何やら嬉しい名前のメソッドが定義されていますw また, index.js の中を見てみますと,
// 省略
import Route from './components/route-hoc.riot'
import Router from './components/router-hoc.riot'
// 省略
export {
// 〜
Router,
Route
}
ふむふむ🤔よくわからないが, 使われているのは確かですね. では上手いことこの onBeforeRoute
を使ってみましょう.
差し込み処理の追加
今回は公式のデモの一つ standalone-history.html をお借りします. <router>, <route>
などのタグベースではなく, JS ベースでのルーティングの実装ですね.
<nav>
<a href="/hello">Hello</a>
<a href="/user">User</a>
<a href="/user/gianluca">Username</a>
<a href="/goodbye">goodbye</a>
</nav>
<div id="root"></div>
<script type="module">
const { initDomListeners, setBase } = route
const loc = window.location
setBase(`${loc.protocol}//${loc.host}`)
const onRoute = (url) => root.innerHTML = `${url} and params=${JSON.stringify(url.params)}`
route.route('/hello').on.value(onRoute)
route.route('/user').on.value(onRoute)
route.route('/user/:username').on.value(onRoute)
route.route('/goodbye').on.value(onRoute)
initDomListeners()
</script>
nav
にリンクが並んでいるだけの簡単な SPA で, クリックすると対応したテキストが下の div タグに表示されます.
ではこちらに onBeforeRoute
メソッドを追加していきます.
<nav>
<a href="/hello">Hello</a>
<a href="/user">User</a>
<a href="/user/gianluca">Username</a>
<a href="/goodbye">goodbye</a>
</nav>
<div id="root"></div>
<script type="module">
const { initDomListeners, setBase } = route
const loc = window.location
setBase(`${loc.protocol}//${loc.host}`)
const onRoute = (url) => root.innerHTML = `${url} and params=${JSON.stringify(url.params)}`
+ const onBeforeRoute = () => {
+ // 現在のルーティングパスを取得し表示
+ alert(route.getCurrentRoute())
+ }
+ route.route('/hello').on.value(onBeforeRoute)
route.route('/hello').on.value(onRoute)
route.route('/user').on.value(onRoute)
route.route('/user/:username').on.value(onRoute)
route.route('/goodbye').on.value(onRoute)
initDomListeners()
</script>
では実行してみましょう.
先に Username
リンクをクリックしており, div タグには /user/gianluca
のテキストが表示されています. ここで Hello
リンクをクリックしたものが↑のキャプチャになります.
alert で表示されるテキストは /hello
となっており, Hello
のルーティングそのものは実行されていますが, まだテキストは書き換わっていないため, レンダリングはブロックされています.
おわりに
あくまでこれは簡易的な方法で, 実際にはこれではダメだと思っています…というのも, 先程の処理を以下のように書き換えると, 先に onRoute!!
のアラートが表示されます.
- const onRoute = (url) => root.innerHTML = `${url} and params=${JSON.stringify(url.params)}`
+ const onRoute = (url) => {
+ root.innerHTML = `${url} and params=${JSON.stringify(url.params)}`
+ alert("onRoute!!")
+ }
const onBeforeRoute = () => {
// 現在のルーティングパスを取得し表示
alert(route.getCurrentRoute())
}
- route.route('/hello').on.value(onBeforeRoute)
route.route('/hello').on.value(onRoute)
+ route.route('/hello').on.value(onBeforeRoute)
これはちょっと細かい話をすると, route は内部的には rawth というライブラリを使っており1 , さらに rawth は内部的には erre というライブラリに依存しています.
で, この子は .on
で検知するルーティングを配列で管理しており, 順番に実行されるため, 先に onRoute!!
が表示される形となります. ですので, route.route('/hello')
で__セットする順番を先に書く必要があります__.
本当は正しい使い方があると思いますが, 一旦これで動いているのでまた何か分かったら更新したいと思います.
ではでは(=゚ω゚)ノ
参考
-
厳密には route のコア機能はほぼ全てこの子の機能 ↩