Ionic Vue でアプリを作ったのでメモ


先月リリースされたIonic Vue を使って簡単なURLメモアプリを作ったので
忘れないようにいくつかメモを残します。

コマンド関係は[クイックスタート](https://ionicframework.com/jp/docs/vue/quickstart)に書いているので省略

ソースは[コチラ](https://github.com/epsilonGtMyon/my-bookmark)

※Android向けのアプリを作ったのでiPhoneでの動作確認はしていません。

## 戻るボタンでアプリを終了する

よくあるAndroidアプリでは物理の戻るボタンを押すことでアプリを終了することができます。

しかしIonicのアプリ(というかCapacitor, というかWebView??)では戻るボタンでひとつ前のページに戻ることはできますが、最初のページで戻るボタンを押してもアプリは終了しません。

そんな時は`useBackButton` と`Capacitor` の`App.exitApp` を使います。

ドキュメントだと[コチラ](https://ionicframework.com/jp/docs/developing/hardware-back-button)です。

こんな感じになります。

```vue:Home.vue
<script lang="ts">
import { Plugins } from "@capacitor/core";
import {
  useBackButton,
  useIonRouter,
} from "@ionic/vue";
import { defineComponent } from "vue";

const { App } = Plugins;

export default defineComponent({
  setup() {
    const ionRouter = useIonRouter();

    //戻るボタンのハンドリング
    useBackButton(10, (processNextHandler) => {
      //アプリを終了してよいかどうかの判定
      if (ionRouter.canGoBack()) {
        //このuseBackButtonは別ページにいるときも呼ばれるので
        //適切にハンドリングしないとダメ
        processNextHandler();
      } else {
        //これ以上戻るページがないので終了
        App.exitApp();
      }
    });

    return {
    };
  },
});
</script>
```

いくつか注意があります。

```js
useBackButton(10, (processNextHandler) => {
  App.exitApp();
});
```

これが本質的な部分なのですが
このように記述してしまった場合、最初のページだけでなく、次のページで戻るボタンを押してもアプリが終了してしまいます。😅

なので対象のページだけで反応してほしいので`router` を使います。

```js
useBackButton(10, (processNextHandler) => {
    if (!ionRouter.canGoBack()) {
       App.exitApp();
    }
});
```

このように書いてしまうと　最初のページのみでアプリが終了するようになるのですが、次のページで戻るボタンを押してもページが戻りません。😅通常時の戻るボタンの動作までキャンセルされています。

そうならないようにするために最初のコードのように`processNextHandler` のコールバックを実行するようにしています。

## ライフサイクルイベントを拾う
`ionViewDidEnter`, `ionViewDidLeave`, `ionViewWillEnter`, `ionViewWillLeave` のことです。

公式ドキュメントでは`Options API` が例として書かれていますが
`Composition API`でも使うことは可能です。

それぞれのライフサイクルイベント名で`setup`関数の戻り値として返せば実行してくれます。

```vue

<script lang="ts">
export default defineComponent({
  setup() {
    const ionViewWillEnter = () => {
      console.log('ionViewWillEnter!!');
    };

    return {
       ionViewWillEnter 
    };
  }
});
</script>
```



## データをスマホに保存する

`Capacitor` の[Storage](https://capacitorjs.com/docs/apis/storage)を使いました。

このドキュメントによると`window.localStorage` に保存するとモバイルOSの場合は定期的にデータが消されるようです。
`Storage` を使うことでそれぞれのモバイルのOSに応じた仕組みが使われるとのことです。

操作は`localStorage` と同様に操作できます。


※[データストレージ](https://ionicframework.com/jp/docs/angular/storage) は調べてないです


## リストデータのソート機能
こんな感じの操作です。

![sample02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628749/e21bf965-ccf8-7346-73e5-7a3a6a6a4e65.gif)


これは
- [ion-reorder](https://ionicframework.com/jp/docs/api/reorder)
- [ion-reorder-group](https://ionicframework.com/jp/docs/api/reorder-group)

を使うことで実装できました。

```vue
<template>
  <!-- 省略-->
    <ion-list>
        <ion-reorder-group
            :disabled="state.disabledReorder"
            @ionItemReorder="reordered"
        >
            <!-- 省略-->
        </ion-reorder-group>
    </ion-list>
      
  <!-- 省略-->
</template>

<script lang="ts">
export default defineComponent({
  setup() {
    //省略
    
    //並び替え時のハンドリング
    const reordered = (event: CustomEvent) => {
      state.bookmarkRecords = event.detail.complete(state.bookmarkRecords);
    };

    //省略
  },
});
</script>
```

ここは公式ドキュメントのそのままの実装ですが
`ionItemReorder` イベントをハンドリングし`event.detail.complete` を呼び出しているだけです。
これだけで状態が変化します。

## 最後に
ひとまず 今回のアプリ作成で使った機能をピックアップしてみました。
まだまだ便利な機能やコンポーネントはたくさんあります

Ionic Vue いいですね