【Ionic/Angular】Tabsテンプレートで作ったIonicアプリにSideBarを追加する
※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。
【目次】
【2020/5/7 追記】
今回の記事の別解を書きました。別解の方がスマートなので、個人的には別解で実装することをオススメします。
【Ionic/Angular】Tabsテンプレートで作ったIonicアプリにSideBarを追加する(別解編) - 大田区から発信するゆるゆる日記
【2020/4/28 追記】
下記の内容では遷移後のページでアクション(イベント)を起こしても反応しないことが分かりました。この記事の内容が多いため、エラー解決方法については別の記事に書かせていただきます。詳しくはこちら【Ionic/Angular】Tabsテンプレートで作ったIonicアプリにSideBarを追加する(エラー対応編) - 大田区から発信するゆるゆる日記をご確認ください。
概要
Tabsテンプレートで作ったIonicアプリにSidebarを追加してみました。意外に躓いたので備忘録にします。
あと恐らくこれはベストプラクティスではないと思います。「こうした方がいいよ」とかあれば、コメントいただければとても嬉しいです。
完成イメージと参考動画
完成イメージはこちらです。
デスクトップではslidebar、スマホではtabsが表示されるようにします。
Ionic Frameworkを用いたデスクトップレイアウトを考える - Qiita
slidebarを追加する際に参考にした動画です。
How to Combine Ionic 4 Tabs and Side Menu Navigation - YouTube
Tabsテンプレートで作ったIonicアプリにSideBarを追加する
ポイント
ポイントはMenuPageのion-split-paneにcontentIdを追加することとmenu-routingのややこしいルーティングです。
contentIdの追加は参考にした動画では追加されていないので忘れがちです。
MenuPageを追加する
Ionicアプリを作成する。
$ ionic start project tabs --type=angular
MenuPageを追加する。
このMenuPageがサイドバーになります。
project $ ionic g page menu
app-routing.module.ts
... const routes: Routes = [ { path: '', loadChildren: () => import('./menu/menu.module').then( m => m.MenuPageModule) } ]; ...
menu.page.html
<ion-split-pane contentId="content"> <ion-menu contentId="content"> <ion-header> <ion-toolbar color="primary"> <ion-title>MENU</ion-title> </ion-toolbar> </ion-header> <ion-content> <ion-list> <ion-menu-toggle auto-hide="false" *ngFor="let p of pages"> <ion-item [routerLink]="p.url" routerDirection="root" [class.active-item]="selectedPath.startsWith(p.url)"> <ion-label> {{p.title}} </ion-label> </ion-item> </ion-menu-toggle> </ion-list> </ion-content> </ion-menu> <ion-router-outlet id="content"></ion-router-outlet> </ion-split-pane>
menu.page.ts
... export class MenuPage { pages = [ { title: 'tab1', url: '/menu/tab1' }, { title: 'tab2', url: '/menu/tab2' }, { title: 'tab3', url: '/menu/tab3' }, ]; selectedPath = ''; constructor(private router: Router) { this.router.events.subscribe((event: RouterEvent) => { if (event && event.url) { this.selectedPath = event.url; } }); } }
menu-routing.module.ts
... const routes: Routes = [ { path: 'menu', component: MenuPage, children: [ { path: 'tab1', children: [ { path: '', loadChildren: () => import('../tab1/tab1.module').then(m => m.Tab1PageModule), }, { path: 'tab1', redirectTo: '', pathMatch: 'full' }, ] }, { path: 'tab2', children: [ { path: '', loadChildren: () => import('../tab2/tab2.module').then(m => m.Tab2PageModule), }, { path: 'tab2', redirectTo: '', pathMatch: 'full' } ] }, { path: 'tab3', children: [ { path: '', loadChildren: () => import('../tab3/tab3.module').then(m => m.Tab3PageModule) }, { path: 'tab3', redirectTo: '', pathMatch: 'full' } ] }, { path: '', redirectTo: '/menu/tab1', pathMatch: 'full' } ] }, ...
タブの表示/非表示を実装する
TabsPageを利用してタブの表示/非表示を実装します。
今回はTabsPageをコンポーネント化してSharedModuleに登録し、各tabに追加していきます。
SharedModuleを作成する
project $ ionic g module shared
tabs.component.ts
... @Component({ selector: 'ls-tabs', templateUrl: 'tabs.component.html', styleUrls: ['tabs.component.scss'] }) export class TabsComponent { constructor() {} } ...
tabs.component.scss
@media screen and (min-width: 992px) { ion-tab-bar { display: none; } }
shared.module.ts
... @NgModule({ imports: [ CommonModule, IonicModule ], declarations: [TabsComponent], exports: [TabsComponent], }) ...
tab1/tab2/tab3.page.html
... </ion-content> <ls-tabs></ls-tabs>
tab1/tab2/tab3.module.ts
imports: [ ... SharedModule, ... ],
タブのルーティングを紐付ける
menu-routing.module.ts
... { path: 'tab3', children: [ { path: '', loadChildren: () => import('../tab3/tab3.module').then(m => m.Tab3PageModule) }, { path: 'tab3', redirectTo: '', pathMatch: 'full' } ] }, { path: 'tab2/tab1', redirectTo: 'tab1', pathMatch: 'full' }, { path: 'tab3/tab1', redirectTo: 'tab1', pathMatch: 'full' }, { path: 'tab1/tab2', redirectTo: 'tab2', pathMatch: 'full' }, { path: 'tab3/tab2', redirectTo: 'tab2', pathMatch: 'full' }, { path: 'tab1/tab3', redirectTo: 'tab3', pathMatch: 'full' }, { path: 'tab2/tab3', redirectTo: 'tab3', pathMatch: 'full' }, { path: '', redirectTo: '/menu/tab1', pathMatch: 'full' } ] }, { path: '', redirectTo: '/menu/tab1', pathMatch: 'full' } ]; ...
今後に向けて
今回はTabsテンプレートを尊重するあまりルーティングがややこしくなってしまいました。
各タブにURLを割り当てていたらもっと簡単になってたのかな...
もっとスマートな方法を知っている方がいましたらコメントお願いします!
参考資料
素晴らしい記事に感謝致します。
ion-split-pane - Ionic Framework 日本語ドキュメンテーション
Angular Lazy LoadingでつまずいちゃうNgModuleのコンポーネント登録 - Qiita
Ionic Frameworkを用いたデスクトップレイアウトを考える - Qiita
How to Combine Ionic 4 Tabs and Side Menu Navigation - YouTube