NCMBのFramework7用UIコンポーネントを使ってスマホアプリを作る（その2：認証と一覧画面）

NCMBはmBaaS（mobile Backend as a Serivce）であり、UIは各フレームワークやプログラミング言語で開発する必要があります。しかし、イチからUIを作るのは大変なことです。

そこで最近、色々なUIコンポーネントを作っています。これらは個々に独立しているので、簡単にアプリ内に導入が可能です。今はFramework7向けに作っていますが、以下のようなUIコンポーネントがあります。

- [地図コンポーネント](https://qiita.com/goofmint/items/20d73a3aad5313f2ecd8)
- [お知らせコンポーネント](https://qiita.com/goofmint/items/ede45debc91df4439da5)
- [ギャラリーコンポーネント](https://qiita.com/goofmint/items/07a5bf7d747b99c16589)
- [認証コンポーネント](https://qiita.com/goofmint/items/6dc28141da611426abc4)
- [リスト・詳細コンポーネント](https://qiita.com/goofmint/items/9df40e8d4117716fe073)
- [フォームコンポーネント](https://qiita.com/goofmint/items/df11f566c35f55fce826)
- [スワイパーコンポーネント](https://qiita.com/goofmint/items/d5bfc38a30c4112dc14a)
- [設定画面コンポーネント](https://qiita.com/goofmint/items/053707151e8a3ada5da4)
- [プロフィール画面コンポーネント](https://qiita.com/goofmint/items/f2a01782bc9149f82ffa)
- [情報リスト画面コンポーネント](https://qiita.com/goofmint/items/286c934cd8445915ae31)

今回は実際にこれらのコンポーネントを使ってアプリを開発する方法を紹介します。前回は[アプリの仕様とSDKの初期化について解説しました](https://qiita.com/goofmint/items/4159ba7e3e5e1069947a)ので、今回は認証コンポーネントとリスト・詳細コンポーネントを利用する流れを解説します。

## index.htmlの編集

まず `www/index.html` を編集します。ここでは `/tabs/` にアクセスするだけです。

```html
<div id="app">
	<div class="view view-init safe-areas" data-url="/tabs/">
	</div>
</div>
```

## tabs.htmlの作成

次に `www/tabs.html` を作成します。このファイルは各UIコンポーネントを読み込むタブバーを実装します。テンプレート部分は次のようになります。

```html
<template>
	<div class="page">
		<div class="navbar">
			<div class="navbar-bg"></div>
			<div class="navbar-inner">
				<div class="left"></div>
				<div class="title">メイン画面</div>
				<div class="right">
					${login ?
						$h`<a class="link" href="#" @click=${logout}>
							<i class="f7-icons">person_badge_plus_fill</i>
						</a>`	 
					:
					$h`<a class="link" href="/login/">
								<i class="f7-icons">person</i>
							</a>`
					}
				</div>
			</div>
		</div>
		<div class="toolbar tabbar-labels toolbar-bottom">
			<div class="toolbar-inner">
				<a href="./" class="tab-link" data-route-tab-id="tab1">
					<i class="icon f7-icons">book</i>
					<span class="tabbar-label">ニュース</span>
				</a>
				<a href="./map/" class="tab-link" data-route-tab-id="tab2">
					<i class="icon f7-icons">map</i>
					<span class="tabbar-label">地図</span>
				</a>
				<a href="./information/" class="tab-link" data-route-tab-id="tab3">
					<i class="icon f7-icons">exclamationmark_circle</i>
					<span class="tabbar-label">情報</span>
				</a>
			</div>
		</div>
		<div class="tabs tabs-routable">
			<div class="page-content tab" id="tab1"></div>
			<div class="page-content tab" id="tab2"></div>
			<div class="page-content tab" id="tab3"></div>
		</div>
	</div>
</template>
```

そしてJavaScript部分では認証状態に応じて `login` 変数を変えて、UI側でもログイン状態によって表示を変えています。

```html
<script>
  export default function (props, {$f7, $on, $update}) {
		let login;
		$on('page:beforein', () => {
			login = !(ncmb.User.getCurrentUser() === null);
			$update();
		});
		const logout = async () => {
			await ncmb.User.logout();
			login = false;
			$update();
		};
		return $render;
	}
</script>
```

最後に `js/routes.js` を開いてルーティングを追加します。タブバーでは初期表示が `/` のコンポーネント呼び出しになります。リスト・情報コンポーネントでは表示するFeedクラスのobjectIdが必要なので、propsで与えています。このobjectIdはアプリによって異なるので注意してください（後述）。

```js
const routes = [
  {
    path: '/',
    url: './index.html',
  },
	// 追加ここから
  {
    path: '/tabs/',
    componentUrl: './pages/tabs.html',
    options: {
      props: {
        objectId: '2YAtnb0nxjjfbeZ3',
      },
    },
    tabs: [
			// リスト・詳細コンポーネント用
      {
        id: 'tab1',
        path: '/',
        componentUrl: './pages/list.html',
      },
			// 地図コンポーネント用
      {
        id: 'tab2',
        path: '/map/',
        componentUrl: './pages/map.html',
      },
			// 情報リスト用
      {
        id: 'tab3',
        path: '/information/',
        componentUrl: './pages/information.html',
      },
    ]
  },
	// 追加ここまで
  // Default route (404 page). MUST BE THE LAST
  {
    path: '(.*)',
    url: './pages/404.html',
  },
];
```

## Feed/Entryクラスの作成

詳細は[NCMBとFramework7を使ったリスト・詳細コンポーネントの紹介と使い方 - Qiita](https://qiita.com/goofmint/items/9df40e8d4117716fe073)に譲りますが、[スクリプト](https://raw.githubusercontent.com/NCMBMania/framework7_list_component/main/script.js)を使ってRSSフィードをデータストアに登録します（スクリプトのアプリケーションキー、クライアントキーは書き換えてください）。

スクリプトはGETにて登録し、 パラメータとして `url=フィードのURL` として実行してください。問題なく完了すれば FeedクラスとEntryクラスができあがりますので、そのFeedクラスのobjectIdを上記 `routes.js` のobjectIdに適用してください。

## 一覧からの画面遷移

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/c1cf1551-ce75-a7c4-8b52-8c915f770c65.png)

記事一覧から詳細画面へ遷移するルーティングを `routes.js` に追加します。 `404.html` のルーティング設定の上に追加してください。

```js
{
	path: '/list/entries/:objectId',
	componentUrl: './pages/detail.html',
},
// ↑追加
// Default route (404 page). MUST BE THE LAST
{
	path: '(.*)',
	url: './pages/404.html',
},
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/374a92c8-3ad6-41de-1314-72bd6f74e47f.png)


これでリスト・詳細コンポーネントの実装が完了です。

## 認証コンポーネントの追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/dd2d223e-756b-7b59-168c-06cb284dce77.png)


認証コンポーネント用のルーティングを `routes.js` に追加します。このコンポーネントでは、画面遷移する前に認証状態を確認しています。もしすでに認証している場合にはトップ画面に戻ります。

```js
{
	path: '/',
	url: './index.html',
},
// ↓追加
{
	path: '/login/',
	componentUrl: './pages/auth.html',
	// 画面遷移前に認証状態を確認
	beforeEnter: function ({ resolve, reject, router }) {
		const user = ncmb.User.getCurrentUser();
		if (user) {
			reject();
			router.navigate('/');
		} else {
			resolve();
		}
	}
},
```

認証コンポーネントの呼び出しは、すでに `tabs.html` に記載済みです。 `/login/` で認証コンポーネントが呼び出されます。

```html
<!-- 記載済み -->
<div class="right">
	${login ?
		$h`<a class="link" href="#" @click=${logout}>
			<i class="f7-icons">person_badge_plus_fill</i>
		</a>`	 
	:
	$h`<a class="link" href="/login/">
				<i class="f7-icons">person</i>
			</a>`
	}
</div>
```

### 認証コンポーネントの修正

認証コンポーネントでは認証後にどこに遷移するかは設定していないので、その部分を修正します。 `pages/auth.html` を開いて修正します。 `$f7router.back()` を有効化して、認証後に前の画面に戻るようにします。

```js
try {
	// ログイン処理
	await ncmb.User.loginWithMailAddress(email, password);
	app.dialog.alert('ログインしました', 'ログイン成功');
	// ↓ コメントアウトされているのを外す
	$f7router.back(); // 戻る場合
} catch (e) {
	// エラーの場合はログインエラー
	app.dialog.alert('メールアドレスとパスワードを確認してください', 'ログインエラー');
}
```

## まとめ

これでリスト・詳細コンポーネントと認証コンポーネントが使えるようになりました。UIコンポーネントを使う際にはHTMLファイルの配置と、ルーティングの設定くらいで利用できます。ぜひ活用してください。

では次回は[地図コンポーネントと情報リストコンポーネントを有効化]()します。