Ionic Vueクイックスタート
Ionic Framework とは
まず、ここに来たばかりの人を歓迎します!Ionic Framework は、 iOS, Android, Electron, Web 上で動作するアプリを構築するための、無償でオープンソースのコンポーネントライブラリです。使い慣れたテクノロジ(HTML、CSS、JavaScript)を使用してアプリケーションを一度作成したら、任意のプラットフォームに展開することができます。
UI コンポーネントに加えて、Ionic Framework は新しいアプリを作るためのコマンドラインツールを提供し、サポートしている様々なプラットフ ォームにデプロイすることができます。
このガイドでは、Ionic Framework 特有の機能を含め、Vue と Ionic Framework の基本について説明します。Vue に精通している方は、ガイドを楽しみ、Ionic Framework について新しいことを学んでください。どちらにも詳しくない方はご安心ください!このガイドでは、基本的なことを説明し、アプリケーションを起動して実行するのに十分な情報を提供します。
Ionic CLI を使ったプロジェクト新規作成
はじめに、Ionic CLI の最新版をインストールしましょう。
npm install -g @ionic/cli@latest
これによって使えるようになった、 グローバルコマンド ionic
によって、Ionic Framework と他の依存関係を持つ Vue プロジェクトを作成することができます。新しいプロジェクトを作成するには、次のコマンドを実行します。
ionic start myApp blank --type vue
cd myApp
これで、 ionic serve
を実行することによって、プロジェクトをブラウザで実行することができます。
TypeScript と JavaScript のどちらで構築するかを選べます
私たちは TypeScript が大好きで、スケールさせるアプリ を構築するための素晴らしいツールだと確信しています。とはいえ、Vue コミュニティがいかにシンプルさを重視しているかは、ツールや言語などでわかっています。実際、そもそも Vue に興味を持ったのはそのおかげかもしれません。シンプルに開始し、必要に応じてスケールアップします。
したがって、TypeScript の代わりに JavaScript を使うことができます。Ionic Vue アプリケーションを生成したら、次の手順を実行してください。
- TypeScript の依存を削除:
npm uninstall --save typescript @types/jest @typescript-eslint/eslint-plugin @typescript-eslint/parser @vue/cli-plugin-typescript @vue/eslint-config-typescript vue-tsc
-
Change all
.ts
files to.js
. In a blank Ionic Vue app, this should only besrc/router/index.ts
andsrc/main.ts
. If you're using tests, also change the extension of files in thetests
directory. -
In
index.html
, change the imported<script>
file from/src/main.ts
to/src/main.js
. -
Remove
@vue/typescript/recommended
and@typescript-eslint/no-explicit-any: ‘off’,
from.eslintrc.js
. -
Remove
Array<RouteRecordRaw>
and the import ofRouteRecordRaw
fromsrc/router/index.js
. -
Delete the
src/shims-vue.d.ts
file if it exists. This is only needed when using the Vue CLI. -
Remove
lang="ts"
from thescript
tags in any of your Vue components that have them. In a blank Ionic Vue app, this should only besrc/App.vue
andsrc/views/HomePage.vue
. -
Delete the
tsconfig.json
file. -
In package.json, change the build script from
"build": "vue-tsc && vite build"
to"build": "vite build"
-
Install terser
npm i -D terser
.
Vue コンポーネントの確認
アプリケーションのベースは src
ディレクトリにあり、メインのエントリポイントは main.ts
になります。エディタでプロジェクトを開き、main.ts
を確認すると、次のように表示されます:
import { createApp } from 'vue';
import { IonicVue } from '@ionic/vue';
import App from './App.vue';
import router from './router';
const app = createApp(App).use(IonicVue).use(router);
router.isReady().then(() => {
app.mount('#app');
});
So what is going on here? The first four lines are pulling in some dependencies. The createApp
function lets us initialize our Vue application, while IonicVue
is a plugin that allows us to use Ionic Framework in a Vue environment.
The third import is the root component for our app, simply named App
. This is our first Vue component and will be used in the bootstrapping process for our Vue app.
The fourth import gets our routing configuration. We will look at this more in depth later.
App.vue
を開くと、次のように表示されます:
<template>
<ion-app>
<ion-router-outlet />
</ion-app>
</template>
<script setup lang="ts">
import { IonApp, IonRouterOutlet } from '@ionic/vue';
</script>
script に書かれている import のグループを分解してみていきましょう。
<script setup lang="ts">
import { IonApp, IonRouterOutlet } from '@ionic/vue';
</script>
To use a component in Vue, you must first import it. So for Ionic Framework, this means anytime we want to use a Button or a Card, it must be added to our imports. In the case of our App
component, we are using IonApp
and IonRouterOutlet
. Vue's script setup
syntax gives the template access to those components as <ion-app>
and <ion-router-outlet>
.
You can also register components globally if you find yourself importing the same components repeatedly. This comes with performance tradeoffs that we cover in Optimizing Your Build.
次に、テンプレートを見てみましょう。
<template>
<ion-app>
<ion-router-outlet />
</ion-app>
</template>
すべての Vue コンポーネントには <template>
が必要です。その中に IonApp
と IonRouterOutlet
のコンポーネントを配置します。
Initializing the router
ルーターのインストール
Ionic Vue は内部的に vue-router を使用しているため、Vue Router にすでに慣れている場合は、これまでの知識を Ionic Vue のナビゲーションに適用できます。先ほど述べたルータの設定 を見てみましょう。router/index.ts
で次のように表示されます。
import { createRouter, createWebHistory } from '@ionic/vue-router';
import { RouteRecordRaw } from 'vue-router';
import HomePage from '@/views/HomePage.vue';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: '/home',
},
{
path: '/home',
name: 'Home',
component: HomePage,
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
この例では、Ionic Vue の Blank starter を使っているので、実際にみる route は少し違うかもしれません
ここでの設定は vue-router
を直接使用する場合と同じですが、代わりに @ionic/vue-router
パッケージから createRouter
や createWebHistory
などの依存関係をインポートする必要があります。
依存関係をインポートした後、 routes
配列に route を宣言できます。そこから、 router インスタンスを作成し、route と使用する history のタイプを提供できます。
Ionic Vue では、遅延ローディングはすぐに使うことができます。 Home
コンポーネントをインポートする代わりに、次の操作を実行することもできます:
const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: '/home',
},
{
path: '/home',
name: 'Home',
component: () => import('@/views/HomePage.vue'),
},
];
Now, you might be wondering: Why do we use @
when describing the path to our components? The @
symbol is a shortcut we can use to describe paths relative to the src
directory. This is useful if we are trying to reference a component while in a file several folders deep. Instead of doing '../../../views/HomePage.vue'
, we could simply do '@/views/HomePage.vue'
.
コンポーネントのスタイル
ここでは、 App
コンポーネントを変更する必要はあまりありません。コンテナコンポーネントの基本的な例です。ルータロジックを設定すると、指定された URL ルートに一致するコンポーネントをレンダリングするだけで済みます。すでに 1 つのコンポーネント/ルータが設定されているので、 Home
コンポーネントを変更しましょう。
現在、 Home
コンポーネントはこうなっています:
<template>
<ion-page>
<ion-header :translucent="true">
<ion-toolbar>
<ion-title>Blank</ion-title>
</ion-toolbar>
</ion-header>
<ion-content :fullscreen="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Blank</ion-title>
</ion-toolbar>
</ion-header>
<div id="container">
<strong>Ready to create an app?</strong>
<p>
Start with Ionic
<a target="_blank" rel="noopener noreferrer" href="https://ionicframework.com/docs/components"
>UI Components</a
>
</p>
</div>
</ion-content>
</ion-page>
</template>
<script setup lang="ts">
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/vue';
</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>
最初に確認した App
コンポーネントと同様に、特定の Ionic Framework コンポーネントのインポート、Vue からのインポート、Vue コンポーネント、そして私たちのコンポーネントに合わせたスタイルがあります。
スタイルに scoped
を指定していることに注目してください。つまり、ここで記述するスタイルは、このコンポーネントにのみ適用されます。これは、スタイルがコンポーネントから漏れてアプリケーションの他の部分に影響するのを防ぐのに役立ちます。Ionic Vue アプリケーションでは、 scoped
のついたスタイルを使用することを強くお勧めします。
IonPage
はすべてのページ(route/URL を持つコンポーネント)の基本コンポーネントであり、header, title, content コンポーネントなど、フルスクリーンコンポーネントの一般的な構成要素がいくつか含まれています。
独自のページを作成する場合は、 IonPage
をそのルート・コンポーネントにすることを忘れないでください。 IonPage
をルートコンポーネントにすることは、Ionic Framework コンポーネント が依存するベース CSS を提供するだけでなく、トランジションが適切に動作することを保証するために重要です。
IonHeader
は、ページの先頭に配置されるコンポーネントです。これは、フレックスボックスベースのレイアウトを処理する以外には、単独ではあまり機能しません。これは、IonToolbar
や IonSearchbar
などのコンポーネントを保持するためのものです。
IonContent
は、その名前が示すように、ページのメインコンテンツ領域です。ユーザーが操作するスクロール可能なコンテンツと、アプリで使用できるスクロールイベントを提供する役割を担っています。
現在のコンテンツは比較的シンプルで実際のアプリで使えるものは何も入っていないので、それを変えましょう。
簡潔に表記するために、関数宣言や他のコンポーネントからのインポート文など、コンポーネントの繰り返し部分を除外します。
<template>
<ion-page>
...
<ion-content>
<ion-list>
<ion-item>
<ion-checkbox label-placement="end" justify="start">
<h1>Create Idea</h1>
<ion-note>Run Idea By Brandy</ion-note>
</ion-checkbox>
<ion-badge color="success" slot="end">5 Days</ion-badge>
</ion-item>
</ion-list>
</ion-content>
</ion-page>
</template>
<script setup lang="ts">
import {
IonBadge,
IonCheckbox,
IonContent,
IonHeader,
IonItem,
IonList,
IonNote,
IonPage,
IonTitle,
IonToolbar,
} from '@ionic/vue';
</script>
ここでは、 IonContent
に IonList
と IonItem
コンポーネントを追加します。ここでは IonItem
を中心に説明します。
<ion-item>
<ion-checkbox label-placement="end" justify="start">
<h1>Create Idea</h1>
<ion-note>Run Idea By Brandy</ion-note>
</ion-checkbox>
<ion-badge color="success" slot="end">5 Days</ion-badge>
</ion-item>
コードを見ると、slot
という特別な属性がある。これは IonItem
がレンダリングする際に、IonBadge
をどこに配置すればよいかを知るための鍵です。これは Vue の API ではなく、Web 標準の API で、多くの Ionic Framework コンポーネントで使われています。また、これは Vue 2 で使用された slots API とは異なります(slots の詳細については、MDN のドキュメントを参照してください)。
Ionic Framework の別のコンポーネントである FAB(フローティング・アクション・ボタン)を見てみましょう。FAB は、アプリケーションの他の部分よりも上位のメイン・アクションを提供する優れた方法です。この FAB には、FAB、FAB ボタンおよびアイコンの 3 つのコンポーネントが必要です。
<template>
<ion-page>
<ion-content>
<ion-list> ... </ion-list>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button>
<ion-icon :icon="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
</ion-page>
</template>
<script setup>
import {
IonBadge,
IonCheckbox,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
IonList,
IonNote,
IonPage,
IonTitle,
IonToolbar,
} from '@ionic/vue';
import { add } from 'ionicons/icons';
</script>
メインの IonFab
では、縦方向と横方向の属性(vertical/horizontal)で表示位置を設定しています。また、slot 属性を使用して、レンダー位置を"fixed"に設定します。これにより、 IonContent
内のスクロール可能なコンテンツの外側でレンダリングするよう IonFab
に指示します。
次に、これにクリックハンドラを設定します。FAB ボタンをクリックすると、新しいページ(この後、すぐに作成します)に移動します。これを行うには、Vue Router のナビゲーション API にアクセスする必要があります。これは useRouter
パッケージから vue-router
をインポートすることで実現できます。
<template>
<ion-page>
<ion-content>
<ion-list> ... </ion-list>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button @click="() => router.push('/new')">
<ion-icon :icon="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
</ion-page>
</template>
<script setup>
import { add } from 'ionicons/icons';
import { useRouter } from 'vue-router';
const router = useRouter();
</script>
このコンポーネントファイルでは、 useRouter
関数をインポートしています。この関数を呼び出すと、コンポーネントからルーティングを操作することができます。つまり、Vue Router から履歴 API にアクセスし、新しい route をナビゲーションスタックにプッシュすることができます。利用方法は IonFabButton
にクリックイベントを追加し、router.push
を呼び出すだけです。この場合、私たちは /new
という route にナビゲーションします。
<ion-fab-button @click="() => router.push('/new')"> ... </ion-fab-button>
新しい route を作成する
これで、アプリケーション内をナビゲートするための環境が整ったので、新しいコンポーネントを作成し、新しい route をルーターの宣言に追加する必要があります。 router/index.ts
を開いて、 new
の route を追加します。
import { createRouter, createWebHistory } from '@ionic/vue-router';
import { RouteRecordRaw } from 'vue-router';
import HomePage from '@/views/HomePage.vue';
import NewItem from '@/views/NewItem.vue';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: '/home',
},
{
path: '/home',
name: 'Home',
component: HomePage,
},
{
path: '/new',
name: 'NewItem',
component: NewItem,
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
route に /new
を追加したので、該当するコンポーネントとなる NewItem
を作成します。これは views/NewItem.vue
に作成します。
新しく NewItem.vue
ファイルを作成します。
<template>
<ion-page>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>New Item</ion-title>
</ion-toolbar>
</ion-header>
<ion-content></ion-content>
</ion-page>
</template>
<script setup lang="ts">
import { IonBackButton, IonButtons, IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/vue';
</script>
Each view must contain an IonPage
component. Page transitions will not work correctly without it. See the IonPage Documentation for more information.
ここでの内容は、 Home
コンポーネントに似ています。異なるのは、 IonBackButton
コンポーネントです。これは、前の route に戻るために使用されます。簡単でしょ?わかりました、でもページをリロードしたらどうなりますか?
この場合、インメモリ内から履歴は失われるため、 戻るボタンは表示されません。この問題を解決するには、 default-href
属性値を、履歴がない場合にナビゲートする URL に設定します。
<ion-back-button default-href="/home"></ion-back-button>
これで、アプリの履歴がない場合も、home route に戻るための戻るボタンを表示することができます。
Calling Methods on Components
In order to call a method on any of the Ionic Vue components, you will first need to get a reference to the component instance. Next, you will need to access the underlying Web Component using $el
and call the method.
In other framework integrations such as Ionic React, this is not needed as any ref
you provide is automatically forwarded to the underlying Web Component instance. We are unable to do the same thing here due to limitations in how Vue manages refs.
<template>
<ion-content ref="content">
<ion-button @click="scrollToBottom">Scroll to Bottom</ion-button>
...
</ion-content>
</template>
<script setup lang="ts">
import { IonButton, IonContent } from '@ionic/vue';
import { ref } from 'vue';
const content = ref();
const scrollToBottom = () => {
content.value.$el.scrollToBottom(300);
};
</script>
Adding Icons
Ionic Vue には Ionicons がプリインストールされています。開発者がアプリケーションで使用できるオプションはいくつかあります。
Per-Component Imports
Per-Component Imports is the recommended approach to using Ionicons. This involves importing the icon of your choice from the ionicons
package and passing it to your template:
<template>
<ion-page>
<ion-content>
<ion-icon :icon="heart"></ion-icon>
</ion-content>
</ion-page>
</template>
<script setup>
import { heart } from 'ionicons/icons';
import { IonContent, IonIcon, IonPage } from '@ionic/vue';
</script>
ここでやっていることを詳しく説明しましょう。まず、 heart
のアイコンを ionicons/icons
からインポートします。これにより、アイコンの適切な SVG データがロードされます。
Then we pass the icon data into the ion-icon
component via the icon
property.
開発者は、モードに応じて異なるアイコンを設定することもできます:
<template>
<ion-page>
<ion-content>
<ion-icon :ios="logoApple" :md="logoAndroid"></ion-icon>
</ion-content>
</ion-page>
</template>
<script setup>
import { logoAndroid, logoApple } from 'ionicons/icons';
import { IonContent, IonIcon, IonPage } from '@ionic/vue';
</script>
Note: これらのアイコン名は、読み込み時にはキャメルケースで読み込む必要があります。
グローバルインポート
もう 1 つのオプションは、特定のアイコンをグローバルにインポートすることです。アプリケーションを起動するたびにアイコンが強制的にロードされ、アプリケーションの初期チャンク・サイズが大きくなる可能性があるため、通常は推奨しません。
とはいえ、特定のアイコンをグローバルにロードすることに意味があるユースケースがあるかもしれません:
main.ts
import { addIcons } from 'ionicons';
import { heart } from 'ionicons/icons';
addIcons({
heart: heart,
});