Ionic Vueが正式にリリースされたからページ遷移のあるアプリを開発してみたよ



# 前提
2020年10月15日にIonic Vueが正式リリースとなりました。
https://ionicframework.com/blog/announcing-ionic-vue/

なので、早速ionic vueを使用してページ遷移を持ったアプリを作成してみました。

# 開発
## 準備

- 最新の ionic CLIをインストールする

```bash
npm install -g @ionic/cli@latest
```

- Typeに Vueを指定してionicアプリを作成する

Startコマンドの[詳細](https://ionicframework.com/jp/docs/cli/commands/start)

```bash
ionic start my-vue-app --type vue
```

- ionic vueのTree構造

```
.
├── babel.config.js
├── capacitor.config.json
├── cypress.json
├── ionic.config.json
├── jest.config.js
├── node_modules
├── package-lock.json
├── package.json
├── public
│   ├── assets
│   └── index.html
├── src
│   ├── App.vue
│   ├── main.ts
│   ├── router
│   ├── shims-vue.d.ts
│   ├── theme
│   └── views
├── tests
│   ├── e2e
│   └── unit
└── tsconfig.json
```

- ローカルで実行する

```bash
ionic serve
```
![スクリーンショット 2020-10-18 21.46.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176216/ef91f89f-e213-f4c1-e79c-b6fe281a2027.png)

と出れば成功。

## 実装

### 遷移先のページを作成

- `src/views/page2.vue`　を作成する
- `page2.vue` 内を作成する

```vuejs:page2.vue
<template>
  <ion-page>
    <ion-header :translucent="true">
      <ion-toolbar>
        <ion-title>Mock Vue</ion-title>
      </ion-toolbar>
    </ion-header>

    <ion-content :fullscreen="true">
      <ion-header collapse="condense">
        <ion-toolbar>
          <ion-title size="large">Page 2</ion-title>
        </ion-toolbar>
      </ion-header>

      <div id="container">
        ページ２です！
      </div>
    </ion-content>
  </ion-page>
</template>

<script lang="ts">
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/vue';
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'Page2',
  components: {
    IonContent,
    IonHeader,
    IonPage,
    IonTitle,
    IonToolbar
  },
});
</script>

<style scoped>
#container {
  text-align: center;
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}

#container strong {
  font-size: 20px;
  line-height: 26px;
}

#container p {
  font-size: 16px;
  line-height: 22px;
  color: #8c8c8c;
  margin: 0;
}

#container a {
  text-decoration: none;
}
</style>
```

### ルーティングを作成する

- `index.ts` 内を下記の用意に修正

```typescript:index.ts
import { createRouter, createWebHistory } from '@ionic/vue-router';
import { RouteRecordRaw } from 'vue-router';
import Home from '../views/home.vue';
import Page2 from '../views/page2.vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    redirect: '/home'
  },
  {
    path: '/home',
    name: 'Home',
    component: Home
  },
  {
    path: '/page2',  // page2 の Pathの追加
    name: 'Page2',
    component: Page2
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router
```

### ページ遷移先の修正

- `home.vue` にページ遷移させるボタンを配置

```vuejs:home.vue
<template>
  <ion-page>
    <ion-header :translucent="true">
      <ion-toolbar>
        <ion-title>Mock Vue</ion-title>
      </ion-toolbar>
    </ion-header>
    <ion-content :fullscreen="true">
      <ion-header collapse="condense">
        <ion-toolbar>
          <ion-title size="large">Page 1</ion-title>
        </ion-toolbar>
      </ion-header>

      <div id="container">
        <!-- 追加 -->
        <ion-button @click="() => router.push('/page2')">ページ２への遷移</ion-button>
      </div>
    </ion-content>
  </ion-page>
</template>

<script lang="ts">
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/vue';
import { useRouter } from 'vue-router'; // 追加
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'Home',
  components: {
    IonContent,
    IonHeader,
    IonPage,
    IonTitle,
    IonToolbar
  },
  setup() { // 追加
    const router = useRouter();
    return { router };
  }
});
</script>

<style scoped>
#container {
  text-align: center;
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}

#container strong {
  font-size: 20px;
  line-height: 26px;
}

#container p {
  font-size: 16px;
  line-height: 22px;
  color: #8c8c8c;
  margin: 0;
}

#container a {
  text-decoration: none;
}
</style>
```

## 成果物
![成果物.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176216/32e8f305-f2c4-5036-9c58-103db594ac7f.gif)



# 感想
- ionic vueのデフォルト言語はTypeScriptであったことに驚いた
- Vueは 1つのコンポーネントの処理を一つのファイルに記載できるので開発が早い
- ionic vueのルーティングはionicの独自実装ではなく、vueの公式ルーティングを使用しており、vue開発者であれば、すごくとっつきやすいと思いました。