Riot.jsのRouteプラグインでSPAのルーティングを実装してみる
Vue.jsが人気の今ですが、あえてRiot.jsで開発しています。学習コストが非常に低く扱いやすいです。Riot.jsでSPA構築の基本であるルーティングの方法を紹介します。
ルーティングのデモ
右上の[全画面ボタン]をクリックして新規タブで見るとURLにハッシュがついて切り替わっているのが分かります。後述しますが、デフォルトでは#(ハッシュ)で、変更することもできます。
ルーティングの基本
<div data-is="navi"></div>
<div data-is="page"></div>
<script src="https://cdn.jsdelivr.net/npm/riot@3.7/riot+compiler.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/riot-route@3.1.2/dist/route.min.js"></script>
<script type="riot/tag">
<navi>
<a each={ items } class="{ is-active: parent.path === url }" href="#{ url }">{ name }</a>
var self = this
this.items = [
{ url: '', name: 'トップ'},
{ url: 'one', name: '1ページ'},
{ url: 'two', name: '2ページ'}
]
var router = route.create()
router(function(path) {
self.path = path
self.update()
})
<style>
:scope {
background-color: #393c40;
}
:scope::after {
display: table;
content: '';
clear: both;
}
a {
display: block;
padding: .5em 1.4em;
float: left;
color: #fff;
text-decoration: none;
font-size: .9em;
}
a.is-active {
color: #fc3b5a;
background-color: #333639;
}
</style>
</navi>
<page>
<p>{ title }</p>
var self = this,
router = route.create()
router('', function() {
self.update({
title: 'トップページのコンテンツが表示されます'
})
})
router('/one', function() {
self.update({
title: '1ページのコンテンツが表示されます'
})
})
router('/two', function() {
self.update({
title: '2ページのコンテンツが表示されます'
})
})
// 404のときはトップへリダイレクト
router('/..', function() {
route('/')
});
<style>
p {
padding: .5em .7em;
font-size: 1.5em;
}
</style>
</page>
</script>
<script>
riot.mount('*')
route.start(true)
</script>
非常にシンプルなので特に解説するところはありませんが、ver3.xからルーティング機能がコアから切り離されたので読み込む必要があります。
URLの#を無くす
ハッシュは少しかっこ悪い気がしたので、スラッシュに変更してみます。ディレクトリは http://localhost:8888
を想定しています。
<div data-is="navi"></div>
<div data-is="page"></div>
<script src="https://cdn.jsdelivr.net/npm/riot@3.7/riot+compiler.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/riot-route@3.1.2/dist/route.min.js"></script>
<script type="riot/tag">
<navi>
<a each={ items } href="{ url }">{ name }</a>
var self = this
this.items = [
{ url: '/', name: 'トップ'},
{ url: '/one', name: '1ページ'},
{ url: '/two', name: '2ページ'}
]
</navi>
<page>
<h1>{ title }</h1>
var self = this,
router = route.create()
route.base('/')
router('', function() {
self.update({
title: 'トップページのコンテンツが表示されます'
})
})
router('/one', function() {
self.update({
title: '1ページのコンテンツが表示されます'
})
})
router('/two', function() {
self.update({
title: '2ページのコンテンツが表示されます'
})
})
// 404のときはトップへリダイレクト
router('/..', function() {
route('/')
});
</page>
</script>
<script>
riot.mount('*')
route.start(true)
</script>
先ほどの例から3箇所変更します。また、route.base('/')
でルーティングのベースディレクトリを指定します。デフォルトはハッシュ route.base('#')
になっています。
<IfModule mod_rewrite.c>
RewriteEngine on
# 末尾にスラッシュがある場合は削除
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# ファイルやディレクトリが存在しなければindex.phpに転送
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
# http://localhost:8888/index.phpにアクセスしたときindex.phpを省略
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^(.*?)index\.php$ $1 [L,R=302,NC,NE]
</IfModule>
また、ブラウザのアドスバーから直接 http://localhost:8888/one
などにアクセスされるとNot Foundとなってしまうので.htaccessファイルに index.php
に転送する処理を書いておきます。
サブディレクトリの場合
ディレクトリが http://localhost:8888/demo/
のようにサブディレクトリである場合はまた少し注意が必要です。
<div data-is="navi"></div>
<div data-is="page"></div>
<script src="https://cdn.jsdelivr.net/npm/riot@3.7/riot+compiler.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/riot-route@3.1.2/dist/route.min.js"></script>
<script type="riot/tag">
<navi>
<a each={ items } href="{ url }">{ name }</a>
var self = this
this.items = [
{ url: '/demo/', name: 'トップ'},
{ url: '/demo/one', name: '1ページ'},
{ url: '/demo/two', name: '2ページ'}
]
</navi>
<page>
<h1>{ title }</h1>
var self = this,
router = route.create()
route.base('demo/')
router('', function() {
self.update({
title: 'トップページのコンテンツが表示されます'
})
})
router('/one', function() {
self.update({
title: '1ページのコンテンツが表示されます'
})
})
router('/two', function() {
self.update({
title: '2ページのコンテンツが表示されます'
})
})
// 404のときはトップへリダイレクト
router('/..', function() {
route('/')
});
</page>
</script>
<script>
riot.mount('*')
route.start(true)
</script>
<IfModule mod_rewrite.c>
RewriteEngine on
# ベースディレクトリを/demoに設定
RewriteBase /demo
# 末尾にスラッシュがある場合は削除
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /demo/$1 [L,R=301]
# ファイルやディレクトリが存在しなければindex.phpに転送
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
# http://localhost:8888/demo/index.phpにアクセスしたときindex.phpを省略
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^(.*?)index\.php$ $1 [L,R=302,NC,NE]
</IfModule>
サブディレクトリに配置する場合は RewriteBase
でベースディレクトリを指定する必要があります。
CSS本執筆しました!!!
CSS本出します!1/29発売予定
— たかもそ@CSS本1/29発売!! (@takamosoo) 2018年12月31日
自分がCSS学びたての頃にもっとはやく知りたかったテクニックを載せています。CSSの基礎知識について解説していないので、中級者〜向けとなります。CSS入門書を読んではみたものの、思い通りに作れない人にオススメです。
よろしくお願いします。https://t.co/fkz1dM03Pj pic.twitter.com/suYyaPqwIs