Stencilは万能、これはガチ!
StencilでPWAを作るときは、
$ npm init stencil
からionic-pwa
を選択して始めるのですが、デフォルトでルーティングがIonicのion-router
を使用するようになっています。
Ionic単体なら@angular/router
を使うのですが、Stencilだとどうやってルーティングするの?ってことであまり記事が見当たらなかったのでココ書いときます。
Ionic3とIonic4のルーティングの違い
Ionic3の場合
Ionic3の時は、ページのコンポーネントをNavController
にpush
したり、pop
してページを遷移していました。
ページ遷移がスタックのような感じでした。
また、ページ間のデータのやり取りも自由で、NavParams
を使って連想配列だろうがカスタムクラスのインスタンスだろうが何でも遷移先のページに渡すことができました。
Ionic4の場合
Ionic4では内部でAngularRouter
が使われています。なので、アプリのrootでページ毎にパスを設定してルーティングするようになりました。
ページ遷移が直線的ですね。
ページ間のやり取りはというと、Ionic3の時の何でも渡せるというのはルーティング使用上あまり推奨はされなくなりました。
id等のユニークな文字列をurlのパラメータとして渡して、遷移先で渡されたデータをサービスに突っ込んで欲しいデータの塊を取得する、という方法が推奨されているようです。
Stencilでion-routerを使ったルーティング
パラメータを渡す
import { Component } from '@stencil/core';
@Component({
tag: 'app-root',
styleUrl: 'app-root.css'
})
export class AppRoot {
render() {
return (
<ion-app>
<ion-router useHash={false}>
<ion-route url="/" component="app-home" />
<ion-route url="/register" component="app-register" />
<ion-route url="/watch/:url" component="app-watch" />
</ion-router>
<ion-nav />
</ion-app>
);
}
}
app-root
でion-router
を使ってルーティングをしています。このコードは
- app-home
- app-register
- app-watch
の3種類のページへのルーティングを行なっており、app-watchに関してはurlというパラメータを受け取れるという意味です。
では、app-watchに遷移する際にパラメータを渡してみましょう。
import { Component, Prop, } from '@stencil/core';
@Component({
tag: 'app-home',
styleUrl: 'app-home.css'
})
export class AppHome {
@Prop() videos: any = [];
constructor() {
this.videos.push({ name: '動画1', url: '動画1のurl', sourceType: 'youtube', tag: '実況動画' });
this.videos.push({ name: '動画2', url: '動画2のurl', sourceType: 'youtube', tag: '実況動画' });
this.videos.push({ name: '動画3', url: '動画3のurl', sourceType: 'youtube', tag: '実況動画' });
this.videos.push({ name: '動画4', url: '動画4のurl', sourceType: 'youtube', tag: '実況動画' });
this.videos.push({ name: '動画5', url: '動画5のurl', sourceType: 'youtube', tag: '実況動画' });
}
render() {
return [
<ion-header>
<ion-toolbar color="primary">
<ion-title>Home</ion-title>
</ion-toolbar>
</ion-header>,
<ion-content padding>
{this.videos.map(video => {
return <ion-card><ion-item href={'/watch/' + video.url}>
<ion-card-title>{video.name}</ion-card-title>
</ion-item></ion-card>
})}
</ion-content>
];
}
}
ダミーデータでvideos
という変数を作りました。
Ionic3では、クリックしたらクリックイベントに紐づいている関数からNavController.push()
って感じでページ遷移してましたが、Ionic4 ではhref
にapp-root.tsx
で指定したurlを設定するだけでページ遷移ができちゃいます。
ここではvideo.url
をパラメータとしてapp-watchページに渡しています。
パラメータを受け取る
import { Component, Prop } from '@stencil/core';
@Component({
tag: 'app-watch',
styleUrl: 'app-watch.css'
})
export class AppWatch {
@Prop() url:string;
async componentDidLoad() {
console.log(this.url);
}
render() {
return [
<ion-header>
<ion-toolbar color="primary">
<ion-title>Watch</ion-title>
</ion-toolbar>
</ion-header>,
<ion-content padding>
<p>
Welcome to the PWA Toolkit. You can use this starter to build entire
apps with web components using Stencil and ionic/core! Check out the
README for everything that comes in this starter out of the box and
check out our docs on <a href="https://stenciljs.com">stenciljs.com</a> to get started.
</p>
</ion-content>
];
}
}
StencilのProp
デコレータを使えば、何と遷移元から渡されたパラメータが代入されます。
なのでコンソールには
動画~のurl
と表示されます。
あとがき
技術書典6のためにStencilの入門本書いてるけど、Stencilできること多いし簡単だしで本書いてて面白い。
興味のある人は4月14日当日ブースに来てもらって話したいところ。
↓はサークルページ
https://techbookfest.org/event/tbf06/circle/60150002