跳到主要内容
版本: v8

Ionic Vue 快速入门

什么是 Ionic 框架?

首先,如果您是新手,欢迎!Ionic 框架是一个免费的开源组件库,用于构建可以在 iOS、Android、Electron 和 Web 上运行的应用程序。使用熟悉的技术(HTML、CSS、JavaScript)编写一次应用程序,并部署到任何平台。

除了 UI 组件外,Ionic 框架还提供一个命令行工具,用于创建新应用程序以及部署到我们支持的各种平台。

在本指南中,我们将介绍 Vue 和 Ionic 框架的基础知识,包括任何 Ionic 框架特定功能。如果您熟悉 Vue,请享受本指南并学习有关 Ionic 框架的更多信息。如果您不熟悉两者,不用担心!本指南将涵盖基础知识并提供足够的信息让您运行应用程序。

使用 Ionic CLI 创建项目

要开始,让我们安装最新版本的 Ionic CLI。

npm install -g @ionic/cli@latest

从这里开始,全局命令 ionic 将允许使用 Ionic 框架以及任何其他依赖项创建 Vue 项目。要创建新项目,请运行以下命令

ionic start myApp blank --type vue
cd myApp

从这里开始,我们运行 ionic serve 并在浏览器中运行我们的项目。

使用 TypeScript 或 JavaScript 构建

我们 Ionic 公司非常喜欢 TypeScript,并且相信它已经成为构建可扩展应用程序的绝佳工具。也就是说,我们知道 Vue 社区多么重视简单性——在他们的工具、语言以及更多方面。事实上,这可能是您最初被吸引到 Vue 的原因。从简单开始——然后根据需要进行扩展。

因此,如果您希望使用 JavaScript 而不是 TypeScript,您可以这样做。在生成 Ionic Vue 应用程序后,请按照以下步骤操作

  1. 删除 TypeScript 依赖项
npm uninstall --save typescript @types/jest @typescript-eslint/eslint-plugin @typescript-eslint/parser @vue/cli-plugin-typescript @vue/eslint-config-typescript vue-tsc
  1. 将所有 .ts 文件更改为 .js。在空白的 Ionic Vue 应用程序中,这应该只包括 src/router/index.tssrc/main.ts。如果您使用测试,也请更改 tests 目录中文件的扩展名。

  2. index.html 中,将导入的 <script> 文件从 /src/main.ts 更改为 /src/main.js

  3. .eslintrc.js 中删除 @vue/typescript/recommended@typescript-eslint/no-explicit-any: ‘off’,

  4. src/router/index.js 中删除 Array<RouteRecordRaw> 以及 RouteRecordRaw 的导入。

  5. 如果存在,请删除 src/vite-env.d.ts 文件。

  6. 从任何具有 lang="ts" 的 Vue 组件的 script 标签中删除 lang="ts"。在空白的 Ionic Vue 应用程序中,这应该只包括 src/App.vuesrc/views/HomePage.vue

  7. 删除 tsconfig.json 文件。

  8. 在 package.json 中,将构建脚本从 "build": "vue-tsc && vite build" 更改为 "build": "vite build"

  9. 安装 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');
});

这里发生了什么?前四行正在引入一些依赖项。createApp 函数允许我们初始化 Vue 应用程序,而 IonicVue 是一个插件,允许我们在 Vue 环境中使用 Ionic 框架。

第三个导入是我们的应用程序的根组件,简单地命名为 App。这是我们的第一个 Vue 组件,将在引导 Vue 应用程序的过程中使用。

第四个导入获取我们的路由配置。我们将在后面更深入地研究它。

如果我们打开 App.vue,我们应该会看到以下内容

<template>
<ion-app>
<ion-router-outlet />
</ion-app>
</template>

<script setup lang="ts">
import { IonApp, IonRouterOutlet } from '@ionic/vue';
</script>

让我们从导入开始分析它。

<script setup lang="ts">
import { IonApp, IonRouterOutlet } from '@ionic/vue';
</script>

要在 Vue 中使用组件,您必须首先导入它。因此,对于 Ionic 框架来说,这意味着无论何时我们想使用按钮或卡片,都必须将它添加到我们的导入项中。在 App 组件的情况下,我们正在使用 IonAppIonRouterOutlet。Vue 的 script setup 语法 使模板能够访问这些组件作为 <ion-app><ion-router-outlet>

如果您发现自己反复导入相同的组件,也可以全局注册组件。这会带来我们在 优化构建 中讨论的性能权衡。

从那里开始,让我们看一下模板。

<template>
<ion-app>
<ion-router-outlet />
</ion-app>
</template>

所有 Vue 组件都必须有一个 <template>。在其中,我们放置 IonAppIonRouterOutlet 组件。

初始化路由器

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 空白入门应用程序,因此您的实际路由可能看起来略有不同。

这里的设置与直接使用 vue-router 相同,但您需要从 @ionic/vue-router 包中导入依赖项,例如 createRoutercreateWebHistory

导入依赖项后,我们可以在 routes 数组中声明我们的路由。从那里开始,我们可以创建一个路由器实例,并为它提供我们的路由以及我们想要使用的历史记录类型。

使用 Ionic Vue,延迟加载开箱即用。我们不导入 Home 组件,而是可以执行以下操作

const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: '/home',
},
{
path: '/home',
name: 'Home',
component: () => import('@/views/HomePage.vue'),
},
];

现在,您可能想知道:为什么在描述组件路径时我们使用 @@ 符号是我们用来描述相对于 src 目录的路径的快捷方式。如果我们尝试在几个文件夹深的某个文件中引用某个组件,这将很有用。我们不执行 '../../../views/HomePage.vue',而是可以简单地执行 '@/views/HomePage.vue'

具有样式的组件

现在,App 组件在这里实际上没有太多需要修改的地方。它是一个容器组件的基本示例。在路由器逻辑设置后,它所负责的只是呈现与给定 URL 路由匹配的组件。由于我们已经有一个组件/路由器设置,让我们继续修改 Home 组件。

目前,Home 组件看起来是这样的

A web browser displaying the Ionic Vue home route with a header titled &#39;Blank&#39; and a message &#39;Ready to create an app? Start with Ionic UI Components&#39;.

<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://ionic.js.cn/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 框架组件的导入项、来自 Vue 的导入项、Vue 组件以及与我们的组件相关的样式。

对于我们的样式,请注意我们已指定样式为 scoped。这意味着我们在这里编写的样式将只应用于此组件。这对于防止样式泄漏到组件之外并影响应用程序的其他部分很有用。我们强烈建议对 Ionic Vue 应用程序使用 scoped 样式。

IonPage 是所有页面的基本组件(具有路由/URL 的组件),并包含全屏组件的一些常见构建块,例如标题、标题和内容组件。

注意

在创建自己的页面时,请不要忘记将IonPage作为其根组件。将IonPage作为根组件很重要,因为它有助于确保过渡正常工作,并提供 Ionic 框架组件所依赖的基本 CSS。

IonHeader 是一个旨在位于页面顶部的组件。它本身不做太多事情,除了处理一些基于 flexbox 的布局。它旨在容纳组件,例如IonToolbarIonSearchbar

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 框架组件中使用。此外,这与您可能从 Vue 2 中回忆起的插槽 API 不同。(有关插槽的更多信息,请参阅此处的 MDN 文档。)

让我们看看 Ionic 框架中的另一个组件,FAB。浮动操作按钮是一种很好的方法,可以提供一个从应用程序其余部分提升的主要操作。对于此 FAB,我们将需要三个组件:一个 FAB、一个 FAB 按钮和一个图标。

<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 上,我们使用垂直和水平属性设置其定位。我们还使用 slot 属性将渲染位置设置为“fixed”。这将告诉IonFabIonContent 中的可滚动内容之外渲染。

现在让我们连接一个点击处理程序。单击 FAB 按钮时,我们希望导航到一个新页面(我们将在稍后创建)。为此,我们需要访问 Vue Router 的导航 API。这可以通过从vue-router 包中导入useRouter 来完成。

<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,从而允许我们将新路由推送到导航堆栈中。在我们的IonFabButton 上,我们可以添加一个点击处理程序,只需调用router.push 并传入新路由。在本例中,我们将导航到new

<ion-fab-button @click="() => router.push('/new')"> ... </ion-fab-button>

创建新路由

现在我们已准备好应用程序中的导航组件,我们需要创建一个新组件并将新路由添加到路由声明中。让我们打开我们的router/index.ts 文件并添加新路由。

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;

现在我们的路由有了/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>
注意

每个视图都必须包含一个IonPage 组件。如果没有它,页面过渡将无法正常工作。有关更多信息,请参阅IonPage 文档

此处的內容應與Home 組件類似。這裡的不同之處在於IonBackButton 組件。這用於導航回前一個路由。看起來很簡單,對吧?好的,但如果我們重新加載页面呢?

在这种情况下,内存历史记录将丢失,因此后退按钮将消失。为了解决这个问题,我们可以将default-href 属性值设置为我们想要导航到的 URL(如果没有历史记录)。

<ion-back-button default-href="/home"></ion-back-button>

现在,如果没有应用程序历史记录存在,我们将能够导航回我们的首页路由。

调用组件上的方法

为了调用任何 Ionic Vue 组件上的方法,您首先需要获取对组件实例的引用。接下来,您需要使用$el 访问底层的 Web 组件并调用该方法。

在其他框架集成(如 Ionic React)中,这是不需要的,因为您提供的任何ref 都将自动转发到底层的 Web 组件实例。由于 Vue 管理 ref 的方式存在局限性,我们无法在此处执行相同的操作。

<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>

添加图标

Ionic Vue 预装了Ionicons。开发人员在应用程序中使用它们有两种选择。

每个组件导入

每个组件导入是使用 Ionicons 的推荐方法。这涉及从ionicons 包中导入您选择 的图标并将其传递给您的模板

<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>

让我们分解一下我们在这里做的事情。首先,我们从ionicons/icons 中导入heart 图标。这将加载我们图标的适当 SVG 数据。

然后,我们将图标数据通过icon 属性传递到ion-icon 组件中。

开发人员还可以根据模式设置不同的图标

<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>

请注意,任何带有连字符的图标名称在导入时都应使用驼峰式大小写。

全局导入

另一种选择是全局导入特定图标。这通常不建议这样做,因为它会强制在应用程序启动时加载图标,并且会增加应用程序的初始块大小。

话虽如此,在某些情况下,全局加载特定图标可能是有意义的

main.ts

import { addIcons } from 'ionicons';
import { heart } from 'ionicons/icons';

addIcons({
heart: heart,
});

HomePage.vue

<template>
<ion-page>
<ion-content>
<ion-icon icon="heart"></ion-icon>
</ion-content>
</ion-page>
</template>

<script setup>
import { IonContent, IonIcon, IonPage } from '@ionic/vue';
</script>

main.ts 中,addIcons 函数让我们能够全局注册图标并为其提供一个字符串作为键。然后,我们在Home 组件中通过该键引用该图标。

优化您的构建

Vue 提供了多种工具来微调您的应用程序。本节将介绍与 Ionic 框架最相关的选项。

默认情况下,Ionic 框架组件是本地注册的。使用本地注册,这些组件被导入并提供给您希望在其中使用它们的每个 Vue 组件。这是推荐的方法,因为它允许延迟加载和摇树优化与 Ionic 框架组件正常工作。

这种方法的一个缺点是,可能需要多次重新导入 Ionic 框架组件,这很繁琐。但是,我们认为您收到的性能优势值得这样做。

还要注意,本地注册的组件在子组件中不可用。您需要重新导入您希望在子组件中使用的 Ionic 框架组件。

让我们看看本地组件注册是如何工作的

<template>
<ion-page>
<ion-content>
<SubComponent></SubComponent>
</ion-content>
</ion-page>
</template>

<script setup lang="ts">
import { IonContent, IonPage } from '@ionic/vue';
import SubComponent from '@/components/SubComponent.vue';
</script>

在上面的示例中,我们使用了IonPageIonContent 组件。要使用它们,我们从@ionic/vue 中导入它们。从那里,我们可以在模板中使用这些组件。

请注意,由于我们是在本地注册这些组件,因此IonPageIonContentSubComponent 中不可用,除非我们也在那里注册它们。

有关更多信息,请参阅本地注册 Vue 文档

全局组件注册

注册组件的另一种选择是使用全局注册。全局注册涉及导入您想在main.ts 中使用的组件,并调用 Vue 应用程序实例上的component 方法。

虽然这使向 Vue 应用程序添加 Ionic 框架组件变得更容易,但全局注册通常并不理想。引用 Vue 文档: "如果您使用的是 Webpack 等构建系统,全局注册所有组件意味着即使您停止使用某个组件,它也可能仍然包含在最终构建中。这会不必要地增加用户需要下载的 JavaScript 数量"。

让我们看看全局组件注册是如何工作的

main.ts

import { IonContent, IonicVue, IonPage } from '@ionic/vue';

const app = createApp(App).use(IonicVue).use(router);

app.component('ion-content', IonContent);
app.component('ion-page', IonPage);

MyComponent.vue

<template>
<ion-page>
<ion-content>
<SubComponent></SubComponent>
</ion-content>
</ion-page>
</template>

<script setup lang="ts">
import SubComponent from '@/components/SubComponent.vue';
</script>

在上面的示例中,我们使用了IonPageIonContent 组件。要使用它们,我们首先从@ionic/vue 中在main.ts 中导入它们。从那里,我们调用应用程序实例上的component 方法,并向其传递标签名称以及组件定义。完成此操作后,我们可以在应用程序的其余部分使用这些组件,而无需将它们导入到每个 Vue 组件中。

有关更多信息,请参阅全局注册 Vue 文档

预取应用程序 JavaScript

默认情况下,Vue CLI 会自动为应用程序中的 JavaScript 生成预取提示。预取利用浏览器的空闲时间下载用户可能在不久的将来访问的文档。当用户访问需要预取文档的页面时,可以从浏览器的缓存中快速提供该文档。

预取会消耗带宽,因此如果您拥有大型应用程序,您可能需要禁用它。您可以通过修改或创建vue.config.js 文件来做到这一点

vue.config.js

module.exports = {
chainWebpack: (config) => {
config.plugins.delete('prefetch');
},
};

上面的配置将阻止所有文件被预取,而是将在需要时加载。您也可以选择某些块进行预取。查看Vue CLI 文档中的预取 了解更多示例。

构建原生应用程序

我们现在已经完成了 Ionic Vue 应用程序的基本知识,包括一些 UI 组件和导航。Ionic 框架组件的优点是它们可以在任何地方使用,包括 iOS、Android 和 PWA。要部署到移动设备和其他平台,我们使用 Ionic 的跨平台应用程序运行时Capacitor。它提供了一组一致的、以 Web 为中心的 API,使应用程序能够尽可能地接近 Web 标准,同时在支持它们的平台上访问丰富的原生设备功能。

添加原生功能很容易。首先,将 Capacitor 添加到您的项目中

ionic integrations enable capacitor

接下来,构建项目,然后添加您选择的平台

ionic build
ionic cap add ios
ionic cap add android

我们使用标准的原生 IDE(Xcode 和 Android Studio)来打开、构建和运行 iOS 和 Android 项目

ionic cap open ios
ionic cap open android

可以在此处 找到更多详细信息。

接下来,查看所有可用的 API。它提供了一些很棒的功能,包括Camera API。我们只需几行代码就可以实现照片捕捉功能

<template>
<ion-page>
<ion-header>
<ion-toolbar>
<ion-title>Ionic Blank</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<img :src="imageSrc" />
<ion-button @click="takePhoto()">Take Photo</ion-button>
</ion-content>
</ion-page>
</template>

<script setup lang="ts">
import { IonButton, IonContent, IonHeader, IonPage, IonTitle } from '@ionic/vue';
import { ref } from 'vue';
import { Camera, CameraResultType } from '@capacitor/camera';

const imageSrc = ref('');
const takePhoto = async () => {
const image = await Camera.getPhoto({
quality: 90,
allowEditing: true,
resultType: CameraResultType.Uri,
});

imageSrc.value = image.webPath;
};
</script>

下一步去哪里

本指南涵盖了创建 Ionic Vue 应用程序的基础知识,添加一些基本导航,并介绍 Capacitor 作为构建原生应用程序的一种方法。要深入了解使用 Vue 和 Capacitor 构建完整的 Ionic 框架应用程序,请访问我们的 第一个应用程序指南

要详细了解 Ionic 框架的组件,请查看 组件 API 页面。有关 Vue 的更多详细信息,请查看 Vue 文档。要继续构建原生功能,请参阅 Capacitor 文档

祝您构建应用愉快!🎉