LoginSignup
8
3

More than 5 years have passed since last update.

StencilJSでion-routerを使ってデータのやり取り

Posted at

Stencilは万能、これはガチ!

StencilでPWAを作るときは、

$ npm init stencil

からionic-pwaを選択して始めるのですが、デフォルトでルーティングがIonicのion-routerを使用するようになっています。

Ionic単体なら@angular/routerを使うのですが、Stencilだとどうやってルーティングするの?ってことであまり記事が見当たらなかったのでココ書いときます。

Ionic3とIonic4のルーティングの違い

Ionic3の場合

Ionic3の時は、ページのコンポーネントをNavControllerpushしたり、popしてページを遷移していました。
ページ遷移がスタックのような感じでした。

また、ページ間のデータのやり取りも自由で、NavParamsを使って連想配列だろうがカスタムクラスのインスタンスだろうが何でも遷移先のページに渡すことができました。

Ionic4の場合

Ionic4では内部でAngularRouterが使われています。なので、アプリのrootでページ毎にパスを設定してルーティングするようになりました。
ページ遷移が直線的ですね。

ページ間のやり取りはというと、Ionic3の時の何でも渡せるというのはルーティング使用上あまり推奨はされなくなりました。
id等のユニークな文字列をurlのパラメータとして渡して、遷移先で渡されたデータをサービスに突っ込んで欲しいデータの塊を取得する、という方法が推奨されているようです。

Stencilでion-routerを使ったルーティング

パラメータを渡す

app-root.tsx
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-rootion-routerを使ってルーティングをしています。このコードは

  • app-home
  • app-register
  • app-watch

の3種類のページへのルーティングを行なっており、app-watchに関してはurlというパラメータを受け取れるという意味です。

では、app-watchに遷移する際にパラメータを渡してみましょう。

app-home.tsx
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 ではhrefapp-root.tsxで指定したurlを設定するだけでページ遷移ができちゃいます。

ここではvideo.urlをパラメータとしてapp-watchページに渡しています。

パラメータを受け取る

app-watch.tsx
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

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3