基于vue3.0的ionic中文开发文档

目录

前言

一、概述

1、Ionic Vue概述

2、Vue版本支持

3、Vue工具

4、原生工具 

5、安装Ionic

二、快速开始

 1、什么是Ionic框架

2、使用 Ionic CLI 创建项目

3、使用 TypeScript 或 JavaScript 构建 

4、一个Vue组件

5、初始化路由器

6、有样式的组件

 7、创建新路由

8、在组件上调用方法

 9、添加图标

(1)在组件中导入 

(2)全局引入

10、优化您的构建

(1)本地组件注册(推荐)

(2)全局注册组件

(3)预提取应用程序 JavaScript 

11、构建原生应用

 三、构建第一个应用

(1)我们要做什么

(2)下载所需工具

 (3)安装Ionic工具

(4)创建应用程序

 (5)PWA元素

 (6)运行应用程序

(7)相册

四、用相机拍照

显示照片 

五、保存照片

六、加载照片 

七、添加手机

八、部署到 iOS 和 Android 

1、安装Capacitor 


前言

        某天水壶哥在开发app时,急需查看ionic的官方api解决一个问题,但不知什么原因,官方api死活上不去,而且水壶哥发现,ionic的官方api时不时的就会挂掉,如果着急查找什么会很耽误事,所幸,趁着ionic官网能访问,将关于vue这部分的app开发文档摘录了下来,以便不时之需。

一、概述

1、Ionic Vue概述

        @ionic/vue 将核心 Ionic 框架体验与为 Vue 开发人员量身定制的工具和 API 相结合。

2、Vue版本支持

        Ionic Vue 建立在 Vue 3.0.0 之上。如果您使用 Ionic Vue 的早期版本构建了一个应用程序,您将需要升级到最新版本并升级您的 Vue 依赖项。

3、Vue工具

        Ionic Vue 项目附带与常规 Vue CLI 项目相同的工具。这意味着您将使用 Vue CLI 及其所有功能进行构建。此外,入门项目还附带了一些默认启用的功能,例如路由和 TypeScript 支持。

4、原生工具 

Capacitor是官方的跨平台应用程序运行时,用于使您的Ionic VueWeb 应用程序在 iOS、Android 和 Web 上本地运行。

Ionic Vue虽然与Cordova插件一起使用没有已知的技术限制,但正式推荐使用 Capacitor。目前没有计划Ionic VueIonic CLI 工具中支持 Cordova 集成。有关详细信息,请参阅此处

5、安装Ionic

$ npm install -g @ionic/cli
$ ionic start myApp tabs --type vue

$ ionic serve

二、快速开始

 1、什么是Ionic框架

        首先,如果你是一位初学者,那么欢迎你!Ionic Framework 是一个免费的开源组件库,用于构建在 iOS、Android、Electron 和 Web 上运行的应用程序。使用熟悉的技术(HTML、CSS、JavaScript)编写您的应用程序并部署到任何平台。

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

        在本指南中,我们将介绍 Vue 和 Ionic 框架的基础知识,包括任何 Ionic 框架特定的功能。如果您熟悉 Vue,请阅读该指南并了解有关 Ionic 框架的新知识。如果您不熟悉其中任何一个,请不要担心!本指南将涵盖基础知识并提供足够的信息来启动和运行应用程序。

2、使用 Ionic CLI 创建项目

        首先,让我们安装最新版本的 Ionic CLI。

npm install -g @ionic/cli@latest

        安装完成后,全局命令ionic将允许使用 Ionic 框架和任何其他依赖项创建 Vue 项目。要创建新项目,请运行以下命令 :

ionic start myApp blank --type vue
cd myApp

         随后,我们可以用ionic serve命令在浏览器中运行我们的项目。

3、使用 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

(2)将所有.ts文件更改为.js. 如果在空白的 Ionic Vue 应用程序中,这应该只是

        router/index.ts文件和main.ts文件

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

(4)Array<RouteRecordRaw>从中删除router/index.js。

(5)删除shims-vue.d.ts 文件

(6)从所有 Vue 组件中的script标签中删除lang="ts"。在空白的 Ionic Vue 应用程序中,这应该只是App.vueand views/Home.vue。

4、一个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 Framework 的插件。

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

        第四个导入获取我们的路由配置。稍后我们将更深入地研究这一点。

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

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

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

  export default defineComponent({
    name: 'App',
    components: {
      IonApp,
      IonRouterOutlet,
    },
  });
</script>

        让我们分解它,从第一组导入开始。 

import { IonApp, IonRouterOutlet } from '@ionic/vue';

        要在 Vue 中使用组件,您必须先导入它。因此对于 Ionic 框架,这意味着任何时候我们想要使用按钮或卡片,都必须将其添加到我们的导入中。对于我们的App组件,我们使用IonAppand IonRouterOutlet。如果您发现自己重复导入相同的组件,您也可以全局注册组件。这伴随着我们在Optimizing Your Build中介绍的性能权衡。 

        再让我们看一下模板。

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

        所有 Vue 组件都必须有一个<template>. 在这里,我们放置我们的IonAppIonRouterOutlet组件。

        最后,我们看一下组件定义:

import { IonApp, IonRouterOutlet } from '@ionic/vue';
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'App',
  components: {
    IonApp,
    IonRouterOutlet,
  },
});

        Vue 3的defineComponent在创建组件以改进工具支持时提供了一个新功能,我们将在这里使用它。我们首先定义组件的名称,然后提供将在模板中使用的组件。

        您可以在此处提供几个参数,例如methods,setup等等。这在 Vue 的Composition API 文档中进行了解释。

5、初始化路由器

        Ionic Vue 使用vue-router依赖项,因此如果您已经熟悉 Vue Router,您将能够将您所知道的应用到 Ionic Vue 中的导航。再来看看我们之前提到的路由器配置。在router/index.ts中,您应该会看到类似于以下内容的内容:

import { createRouter, createWebHistory } from '@ionic/vue-router';
import { RouteRecordRaw } from 'vue-router';
import Home from '@/views/Home.vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    redirect: '/home',
  },
  {
    path: '/home',
    name: 'Home',
    component: Home,
  },
];

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

export default router;

注意

此示例使用 Ionic Vue Blank空白项目启动应用程序,因此您的实际路由可能并不与此完全相同。

        这里的设置和你vue-router直接使用一样,但是你需要从包中导入依赖项,例如createRouter和。createWebHistory@ionic/vue-router

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

        使用 Ionic Vue,延迟加载开箱即用。除了导入我们的Home组件,我们还可以这样做:

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

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

6、有样式的组件

        以上的App组件并没有太多需要修改的地方。它是容器组件的基本示例。使用路由器逻辑集,它所负责的只是渲染与给定 URL 路由匹配的组件。由于我们已经设置了一个组件/路由器,让我们继续修改我们的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 lang="ts">
  import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/vue';
  import { defineComponent } from 'vue';

  export default defineComponent({
    name: 'Home',
    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>

        就像我们开始使用App的组件时一样,我们有一些针对特定 Ionic 框架导入的组件,和一些从 Vue 导入的组件,以及与我们的组件一起使用的样式。

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

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

注意

创建自己的页面时,不要忘记使用IonPage做为根组件。使用IonPage根组件很重要,因为它有助于确保转换正常工作,并提供 Ionic Framework 组件所依赖的基本 CSS。

  IonHeader是一个存在于页面顶部的组件。除了处理一些基于 flexbox 的布局之外,它本身并没有做太多事情。它一般用于存放类似IonToolbar或IonSearchbar的组件

  IonContent顾名思义,是我们页面的主要内容区域。它负责提供用户将与之交互的可滚动内容,以及可在应用程序中使用的任何滚动事件。

        我们当前的内容相对简单,但不包含任何可以在实际应用程序中使用的内容,所以让我们对其进行更改。

注意

为简洁起见,我们排除了组件的重复部分,例如函数声明或来自其他组件的导入语句。

<template>
  <ion-page>
    ...
    <ion-content>
      <ion-list>
        <ion-item>
          <ion-checkbox slot="start"></ion-checkbox>
          <ion-label>
            <h1>Create Idea</h1>
            <ion-note>Run Idea By Brandy</ion-note>
          </ion-label>
          <ion-badge color="success" slot="end"> 5 Days </ion-badge>
        </ion-item>
      </ion-list>
    </ion-content>
  </ion-page>
</template>

        在IonContent组件中,我们添加了一个IonList组件。让我们看看它的核心IonItem组件

<ion-item>
  <ion-checkbox slot="start"></ion-checkbox>
  <ion-label>
    <h1>Create Idea</h1>
    <ion-note>Run Idea By Brandy</ion-note>
  </ion-label>
  <ion-badge color="success" slot="end"> 5 Days </ion-badge>
</ion-item>

        这里有一个特殊的属性,称为 slot。这是在渲染IonItem组价中的IonCheckbox组件时,明确放置位置的关键。IonCheckbox不是 Vue API,而是 Web 标准 API。此外,这与您可能从 Vue 2 中回忆的插槽 API 不同。

        让我们看看 Ionic Framework 的另一个组件 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>
  import { add } from 'ionicons/icons';

  ...

  export default defineComponent({
    name: 'Home',
    ...,
    setup() {
      return {
        add
      }
    }
  })
</script>

        在我们的 IonFab上,我们使用垂直和水平属性设置它的位置。我们还使用 slot 属性将渲染位置设置为“固定”。这将告诉 IonFab 在 IonContent 中的可滚动内容之外呈现。

        现在让我们连接一个点击处理程序。单击 FAB 按钮时,我们希望导航到一个新页面(稍后我们将创建该页面)。为此,我们需要访问 Vue Router 的导航 API。这可以通过useRoutervue-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>
  import { add } from 'ionicons/icons';
  import { useRouter } from 'vue-router';

  ...

  export default defineComponent({
    name: 'Home',
    components: {
      IonContent,
      IonFab,
      IonFabButton,
      IonHeader,
      IonIcon,
      IonPage,
      IonTitle,
      IonToolbar
    },
    setup() {
      return {
        router: useRouter(),
        add
      }
    }
  });
</script>

        在我们的组件文件中,我们正在导入useRouter函数。调用时,此函数将路由器依赖项注入到组件中。它使我们能够从 Vue Router 访问历史 API,允许我们将新路由推送到导航堆栈。在我们的IonFabButton中,我们可以添加一个点击处理程序,然后调用router.push并传入新路由。在这种情况下,我们将导航到new

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

 7、创建新路由

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

import { createRouter, createWebHistory } from '@ionic/vue-router';
import { RouteRecordRaw } from 'vue-router';
import Home from '@/views/Home.vue';
import NewItem from '@/views/NewItem.vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    redirect: '/home',
  },
  {
    path: '/home',
    name: 'Home',
    component: Home,
  },
  {
    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>
  import { IonBackButton, IonButtons, IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/vue';
  import { defineComponent } from 'vue';

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

注意

每个视图必须包含一个IonPage组件。没有它,页面转换将无法正常工作。有关详细信息,请参阅IonPage 文档

        这里的内容应该与Home组件类似。这里不同的是IonBackButton组件。这用于导航回之前的路线。看起来很容易,对吧?好的,但是如果我们重新加载页面呢?

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

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

        现在,如果没有应用历史记录,我们将能够导航回我们的主页上。

8、在组件上调用方法

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

        在 Ionic React 等其他框架集成中,这不是必需的,因为ref您提供的任何内容都会自动转发到底层 Web 组件实例。由于 Vue 管理 refs 的限制,我们无法在这里做同样的事情。

<template>
  <ion-content ref="content">
    <ion-button @click="scrollToBottom">Scroll to Bottom</ion-button>

    ...
  </ion-content>
</template>

<script lang="ts">
  import { IonButton, IonContent } from '@ionic/vue';
  import { defineComponent, ref } from 'vue';

  export default defineComponent({
    components: { IonButton, IonContent },
    setup() {
      const content = ref();
      const scrollToBottom = () => {
        content.value.$el.scrollToBottom(300);
      };

      return { content, scrollToBottom };
    },
  });
</script>

 9、添加图标

        Ionic Vue 预装了Ionicons。开发人员可以在他们的应用程序中通过以下几种方式使用它们。

(1)在组件中导入 

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

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

<script>
  import { heart } from 'ionicons/icons';
  import { IonContent, IonPage } from '@ionic/vue';
  import { defineComponent } from 'vue';

  export default defineComponent({
    name: 'Icon',
    components: {
      IonContent,
      IonPage,
    },
    setup() {
      return { heart };
    },
  });
</script>

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

        接下来,通过heart在方法中将数据传递给我们的模板setup

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

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

<template>
  <ion-page>
    <ion-content>
      <ion-icon :ios="logoApple" :md="logoAndroid"></ion-icon>
    </ion-content>
  </ion-page>
</template>

<script>
  import { logoAndroid, logoApple } from 'ionicons/icons';
  import { IonContent, IonPage } from '@ionic/vue';
  import { defineComponent } from 'vue';

  export default defineComponent({
    name: 'Icon',
    components: {
      IonContent,
      IonPage,
    },
    setup() {
      return { logoAndroid, logoApple };
    },
  });
</script>

注意

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

(2)全局引入

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

        全局加载图标的用例如下:

 main.ts

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

addIcons({
  heart: heart,
});

Home.vue

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

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

  export default defineComponent({
    name: 'Home',
    components: {
      IonContent,
      IonPage,
    },
  });
</script>

        在main.ts中,该addIcons函数允许我们全局注册图标并给它一个字符串作为键。然后,我们在Home组件中通过该键引用图标。

10、优化您的构建

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

(1)本地组件注册(推荐)

        默认情况下,Ionic Framework 组件在本地注册。通过本地注册,这些组件被导入并提供给您想要使用它们的每个 Vue 组件。这是推荐的方法,因为它允许延迟加载和 treeshaking 与 Ionic Framework 组件一起正常工作。

        这种方法的一个缺点是多次重新导入 Ionic Framework 组件可能很乏味。但是,我们认为您获得的性能收益是值得的。

        另请注意,本地注册的组件在子组件中不可用。您需要重新导入要在子组件中使用的 Ionic Framework 组件。

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

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

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

  export default defineComponent({
    components: { IonContent, IonPage, Subcomponent },
  });
</script>

        在上面的示例中,我们使用了IonPage和IonContent组件。要使用它们,我们首先从@ionic/vue中导入,然后,我们在选项中将它们提供给我们的 Vue 组件。从那里,我们可以使用模板中的组件。

        请注意,由于我们是在本地注册的IonPage和IonContent组件,在子组件中必须重新注册才可以使用。

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

(2)全局注册组件

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

        虽然这使得将 Ionic Framework 组件添加到您的 Vue 应用程序变得更加容易,但全局注册通常并不推荐。就像 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 lang="ts">
  import { defineComponent } from 'vue';
  import Subcomponent from '@/components/Subcomponent.vue';

  export default defineComponent({
    components: { Subcomponent },
  });
</script>

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

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

(3)预提取应用程序 JavaScript 

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

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

 vue.config.js

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

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

11、构建原生应用

        我们现在已经掌握了 Ionic Vue 应用程序的基础知识,包括一些 UI 组件和导航。Ionic Framework 组件的伟大之处在于它们可以在任何地方工作,包括 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="photo" />
      <ion-button @click="takePhoto()">Take Photo</ion-button>
    </ion-content>
  </ion-page>
</template>

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

  export default defineComponent({
    name: 'Home',
    components: {
      IonButton,
      IonContent,
      IonHeader,
      IonPage,
      IonTitle,
    },
    setup() {
      const imageSrc = ref('');
      const takePhoto = async () => {
        const image = await Camera.getPhoto({
          quality: 90,
          allowEditing: true,
          resultType: CameraResultType.Uri,
        });

        imageSrc.value = image.webPath;
      };

      return {
        photo: imageSrc,
        takePhoto,
      };
    },
  });
</script>

 三、构建第一个应用

        Ionic 的伟大之处在于,通过一个代码库,您可以只使用 HTML、CSS 和 JavaScript 为任何平台构建。跟随我们一步一步地创建一个真实的应用程序来学习 Ionic 应用程序开发的基础知识。

(1)我们要做什么

        我们将创建一个 Photo Gallery 应用程序,该应用程序提供使用您设备的相机拍摄照片、将它们显示在网格中并将它们永久存储在设备上的功能。

亮点包括:

在 GitHub 上查找本指南中引用的完整应用程序代码。

(2)下载所需工具

        立即下载并安装这些以确保最佳的 Ionic 开发体验:

  • 用于与 Ionic 生态系统交互的Node.js。在此处下载 LTS 版本
  • 用于...编写代码的代码编辑器!我们是Visual Studio Code的粉丝。
  • 命令行界面/终端(CLI)
    • Windows用户:为获得最佳 Ionic 体验,我们建议使用内置命令行 (cmd) 或 Powershell CLI,以管理员模式运行。
    • Mac/Linux用户,几乎任何终端都可以使用。

 (3)安装Ionic工具

        在命令行终端中运行以下命令来安装 Ionic CLI ( ionic),native-run用于在设备和模拟器/模拟器上运行本机二进制文件,以及cordova-res用于生成本机应用程序图标和启动屏幕: 

注意

要在 Visual Studio Code 中打开终端,请转到终端 -> 新终端。

npm install -g @ionic/cli@latest native-run cordova-res

注意

-g选项意味着全局安装。全局安装包时,EACCES可能会发生权限错误。

考虑将 npm 设置为在没有提升权限的情况下全局运行。有关详细信息,请参阅解决权限错误

(4)创建应用程序

        接下来,创建一个 Ionic Vue 应用程序,该应用程序使用“Tabs”启动模板并添加 Capacitor 以实现本机功能: 

ionic start photo-gallery tabs --type vue --capacitor

        这个入门项目包含三个预先构建的页面和 Ionic 开发的最佳实践。有了通用的构建块,我们可以轻松添加更多功能!

        接下来,切换到 app 文件夹:

cd photo-gallery

         接下来,我们需要安装必要的 Capacitor 插件以使应用程序的本机功能正常工作:

npm install @capacitor/camera @capacitor/storage @capacitor/filesystem

 (5)PWA元素

        一些 Capacitor 插件,包括 Camera API,通过 Ionic PWA Elements 库提供基于 Web 的功能和 UI 。

        这是一个单独的依赖项,所以接下来安装它:

npm install @ionic/pwa-elements

        安装后,在您选择的代码编辑器中打开项目。

        接下来,通过编辑src/main.ts.导入@ionic/pwa-elements

// Above the createApp() line
import { defineCustomElements } from '@ionic/pwa-elements/loader';

// Call the element loader after the platform has been bootstrapped
defineCustomElements(window);

 (6)运行应用程序

        在你的 命令行中运行这个命令:

ionic serve

(7)相册

        有三个选项卡。单击 Tab2 选项卡。这是一块空白的画布,也就是变成照片库的理想场所。Ionic CLI 具有实时重新加载功能,因此当您进行更改并保存它们时,应用程序会立即更新!

        打开/src/views/Tab2.vue. 我们看: 

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

      <ExploreContainer name="Tab 2 page" />
    </ion-content>
  </ion-page>
</template>

        我们将应用程序的视觉方面放入<ion-content>. 在这种情况下,我们将在其中添加一个按钮,用于打开设备的摄像头并显示摄像头捕获的图像。但首先,删除ExploreContainer组件,从 import 语句开始:

import ExploreContainer from '@/components/ExploreContainer.vue';

        接下来,从Default Export 和 HTMLExploreContainer的列表中删除组件名称 ( ) :components 

<ExploreContainer name="Tab 2 page" />

        我们将用浮动操作按钮(FAB) 替换它。首先,更新<script>标签中的导入以包含相机图标以及我们将很快使用的一些 Ionic 组件: 

import { camera, trash, close } from 'ionicons/icons';
import {
  IonPage,
  IonHeader,
  IonFab,
  IonFabButton,
  IonIcon,
  IonToolbar,
  IonTitle,
  IonContent,
  IonGrid,
  IonRow,
  IonCol,
  IonImg,
} from '@ionic/vue';

        接下来,将我们将使用的新 Ionic 组件添加到默认导出中,并在setup()方法中返回 Ionicons(Composition API的一部分):

export default {
  name: 'Tab2',
  components: {
    IonPage,
    IonHeader,
    IonFab,
    IonFabButton,
    IonIcon,
    IonToolbar,
    IonTitle,
    IonContent,
    IonGrid,
    IonRow,
    IonCol,
    IonImg,
  },
  setup() {
    return {
      camera,
      trash,
      close,
    };
  },
};

        然后,将 FAB 添加到页面底部。使用摄像头图像作为图标,takePhoto()点击该按钮时调用该函数(即将实现):

<ion-content :fullscreen="true">
  <ion-fab vertical="bottom" horizontal="center" slot="fixed">
    <ion-fab-button @click="takePhoto()">
      <ion-icon :icon="camera"></ion-icon>
    </ion-fab-button>
  </ion-fab>
</ion-content>

        稍后我们将创建takePhoto使用相机和其他原生功能的方法和逻辑。

        接下来,打开src/views/TabsPage.vue删除图标ellipse并改为导入图标images

import { images, square, triangle } from 'ionicons/icons';

        在标签栏 ( <ion-tab-bar>) 中,将标签更改为“照片”,将中间标签按钮的ellipse图标更改为:images

<ion-tab-button tab="tab2" href="/tabs/tab2">
  <ion-icon :icon="images" />
  <ion-label>相册</ion-label>
</ion-tab-button>

        最后在setup() 方法中将ellipse替换为images

  setup() {
    return {
      images,
      square,
      triangle,
    }
  }

四、用相机拍照

        添加使用 Capacitor Camera API使用设备相机拍照的功能。我们将从为 Web 构建它开始,然后进行一些小的调整以使其在移动设备(iOS 和 Android)上运行。

        为此,我们将创建一个与 Vue 的 Composition API 配对的独立合成函数来管理画廊的照片。

注意

如果你不熟悉 Vue 的 Composition API,为什么选择 Composition API?Vue 官方文档是一个很好的入门资源。

        创建一个新文件src/composables/usePhotoGallery.ts并打开它。

        我们将首先从 Vue 核心和 Capacitor 导入我们将使用的各种实用程序:

import { ref, onMounted, watch } from 'vue';
import { Camera, CameraResultType, CameraSource, Photo } from '@capacitor/camera';
import { Filesystem, Directory } from '@capacitor/filesystem';
import { Storage } from '@capacitor/storage';

        接下来,创建一个名为 usePhotoGallery 的函数: 

export function usePhotoGallery() {
  const takePhoto = async () => {
    const photo = await Camera.getPhoto({
      resultType: CameraResultType.Uri,
      source: CameraSource.Camera,
      quality: 100,
    });
  };

  return {
    takePhoto,
  };
}

        我们的usePhotoGallery函数公开了一个名为 takePhoto 的方法,该方法又调用 Capacitor Camera API 的getPhoto方法。

        请注意这里的神奇之处:没有特定于平台的代码(Web、iOS 或 Android)!Capacitor Camera 插件为我们抽象了这一点,只留下一个方法调用 -getPhoto()这将打开设备的相机并允许我们拍照。

        我们需要采取的最后一步是使用 Tab2 页面中的新功能。回到 Tab2.vue 并导入它:

import { usePhotoGallery } from '@/composables/usePhotoGallery';

        接下来,在默认导出中,添加一个 setup 方法,它是Composition API的一部分。从usePhotoGallery中解构takePhoto函数,然后返回它: 

<script lang="ts">
import { camera, trash, close } from 'ionicons/icons';
import { IonPage, IonHeader, IonFab, IonFabButton, IonIcon,
         IonToolbar, IonTitle, IonContent, IonGrid, IonRow,
         IonCol, IonImg } from '@ionic/vue';
import { usePhotoGallery } from '@/composables/usePhotoGallery';

export default  {
  name: 'Tab2',
  components: { IonPage, IonHeader, IonFab, IonFabButton, IonIcon,
         IonToolbar, IonTitle, IonContent, IonGrid, IonRow,
         IonCol, IonImg },
  setup() {
    const { takePhoto } = usePhotoGallery();

    return {
      takePhoto,
      camera, trash, close
    }
  }
}
</script>

        在照片库选项卡上,单击相机按钮。如果您的计算机有任何类型的网络摄像头,则会出现一个模式窗口。自拍一张(由于种种原因,我并没有露脸)!

         拍照后,它立即消失。我们仍然需要在我们的应用程序中显示它并保存它以供将来访问。

显示照片 

        首先,我们将创建一个新类型来定义我们的照片,它将保存特定的元数据。将以下 UserPhoto 接口添加到usePhotoGallery.ts文件中,在 main 函数之外的某个位置:

export interface UserPhoto {
  filepath: string;
  webviewPath?: string;
}

        回到函数的顶部(在引用 Capacitor Camera 插件之后),定义一个数组,以便我们可以存储使用相机拍摄的每张照片。使用 Vue 的ref 函数使其成为反应变量。

const photos = ref<UserPhoto[]>([]);

        当相机完成拍照后,Photo从 Capacitor 返回的结果将被添加到photos数组中。更新takePhoto方法,在Camera.getPhoto之后添加以下代码: 

const fileName = new Date().getTime() + '.jpeg';
const savedFileImage = {
  filepath: fileName,
  webviewPath: photo.webPath,
};

photos.value = [savedFileImage, ...photos.value];

        接下来,更新 return 语句以包含 photos 数组: 

return {
  photos,
  takePhoto,
};

        回到 Tab2 组件,更新 import 语句以包含UserPhoto接口: 

import { usePhotoGallery, UserPhoto } from '@/composables/usePhotoGallery';

        然后,访问照片数组: 

const { photos, takePhoto } = usePhotoGallery();

        最后,添加photos返回setup()

return {
  photos,
  takePhoto,
  camera,
  trash,
  close,
};

        将照片存储到主数组中,我们现在可以在屏幕上显示图像。添加一个Grid 组件,以便每张照片在添加到图库时都能很好地显示,并循环遍历 photos 数组中的每张照片,为每张照片添加一个 Image 组件 ( <ion-img>)。将src(源)指向照片的路径:

<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col size="6" :key="photo" v-for="photo in photos">
        <ion-img :src="photo.webviewPath"></ion-img>
      </ion-col>
    </ion-row>
  </ion-grid>

  <!-- <ion-fab> markup  -->
</ion-content>

        保存所有文件。在网络浏览器中,单击相机按钮并拍摄另一张照片。这一次,照片显示在照片库中!

        接下来,我们将添加对将照片保存到文件系统的支持,以便以后可以在我们的应用程序中检索和显示它们。

五、保存照片

        我们现在可以拍摄多张照片并将它们显示在我们应用程序第二个选项卡上的照片库中。但是,这些照片目前并未永久存储,因此当应用程序关闭时,它们将丢失。

        幸运的是,将它们保存到文件系统只需要几个步骤。首先打开usePhotoGallery函数 ( src/composables/usePhotoGallery.ts),然后从Filesystem类中访问writeFile方法:

        接下来,创建几个新函数。文件系统 API 要求写入磁盘的文件作为 base64 数据传入,因此稍后将使用此辅助函数来协助:

const convertBlobToBase64 = (blob: Blob) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onerror = reject;
    reader.onload = () => {
      resolve(reader.result);
    };
    reader.readAsDataURL(blob);
  });

        接下来,添加一个将照片保存到文件系统的函数。我们传入photo表示新捕获的设备照片的对象以及文件名,该文件名将为要存储的文件提供路径。

        接下来我们使用 Capacitor Filesystem API将照片保存到文件系统。我们首先将照片转换为 base64 格式,然后将数据提供给 Filesystem 的writeFile函数:

const savePicture = async (photo: Photo, fileName: string): Promise<UserPhoto> => {
  let base64Data: string;

  // Fetch the photo, read as a blob, then convert to base64 format
  const response = await fetch(photo.webPath!);
  const blob = await response.blob();
  base64Data = (await convertBlobToBase64(blob)) as string;

  const savedFile = await Filesystem.writeFile({
    path: fileName,
    data: base64Data,
    directory: Directory.Data,
  });

  // Use webPath to display the new image instead of base64 since it's
  // already loaded into memory
  return {
    filepath: fileName,
    webviewPath: photo.webPath,
  };
};

        最后,更新takePhoto要调用的函数savePicture。保存照片后,将其插入反应photos数组的前面: 

const takePhoto = async () => {
  const photo = await Camera.getPhoto({
    resultType: CameraResultType.Uri,
    source: CameraSource.Camera,
    quality: 100,
  });

  const fileName = new Date().getTime() + '.jpeg';
  const savedFileImage = await savePicture(photo, fileName);

  photos.value = [savedFileImage, ...photos.value];
};

        这样,每次拍摄新照片时,它都会自动保存到文件系统中。 

六、加载照片 

        我们已经实现了拍照并保存到文件系统。缺少最后一项功能:照片存储在文件系统中,但我们需要一种方法来保存指向每个文件的指针,以便它们可以再次显示在照片库中。

        幸运的是,这很容易:我们将利用 Capacitor Storage API将我们的照片数组存储在键值存储中。

        首先定义一个常量变量,该变量将作为usePhotoGallery函数顶部的存储键

const PHOTO_STORAGE = 'photos';

        接下来,添加一个cachePhotos将 Photos 数组作为 JSON 保存到文件存储的函数: 

const cachePhotos = () => {
  Storage.set({
    key: PHOTO_STORAGE,
    value: JSON.stringify(photos.value),
  });
};

        接下来,使用 Vue 的watch 函数来观察photos数组。每当阵列被修改(在这种情况下,拍摄或删除照片),触发该cachePhotos功能。我们不仅可以重用代码,而且应用程序用户何时关闭或切换到其他应用程序也无关紧要 - 始终保存照片数据。 

watch(photos, cachePhotos);

        现在照片数组数据已保存,创建一个函数以在 Tab2 加载时检索数据。首先,从 Storage 中检索照片数据,然后将每张照片的数据转换为 base64 格式: 

const loadSaved = async () => {
  const photoList = await Storage.get({ key: PHOTO_STORAGE });
  const photosInStorage = photoList.value ? JSON.parse(photoList.value) : [];

  for (const photo of photosInStorage) {
    const file = await Filesystem.readFile({
      path: photo.filepath,
      directory: Directory.Data,
    });
    photo.webviewPath = `data:image/jpeg;base64,${file.data}`;
  }

  photos.value = photosInStorage;
};

        在移动设备上(下一节会讲到!),我们可以直接将图像标签的来源设置为<img src="x" />文件系统上的每个照片文件,并自动显示它们。然而,在 Web 上,我们必须将文件系统中的每个图像读取为 base64 格式,因为文件系统 API 将它们存储在底层 IndexedDB中的 base64 中。

        最后,我们需要一种在loadSaved加载照片库页面时调用该函数的方法。为此,请使用 Vue安装的生命周期钩子。首先,onMounted从 Vue 导入:

import { ref, onMounted, watch } from 'vue';

        然后,在usePhotoGallery函数中,添加onMounted函数并调用loadSaved: 

onMounted(loadSaved);

        至此,我们在可在网络上运行的 Ionic 应用程序中构建了一个完整的照片库功能。接下来,我们将把它变成一个适用于 iOS 和 Android 的移动应用程序! 

七、添加手机

        在 iOS、Android 和 Web 上运行之前,我们的照片库应用程序并不完整——所有这些都使用一个代码库。只需要一些小的逻辑更改来支持移动平台,安装一些本地工具,然后在设备上运行应用程序。我们走吧!

        让我们从进行一些小的代码更改开始——然后我们的应用程序将在我们将其部署到设备时“正常工作”。

        首先,我们将更新照片保存功能以支持移动设备。我们将根据平台(移动设备或网络)运行略有不同的代码。从 Ionic Vue导入PlatformAPI:

import { isPlatform } from '@ionic/vue';

        在savePicture函数中,检查应用程序在哪个平台上运行。如果是“混合”(Capacitor,本机运行时),则使用该readFile方法将照片文件读取为 base64 格式。此外,使用 Filesystem API 返回照片的完整文件路径。设置时webviewPath,请使用特殊Capacitor.convertFileSrc方法(此处详细说明)。否则,在 web 上运行应用程序时使用与以前相同的逻辑。

const savePicture = async (photo: Photo, fileName: string): Promise<UserPhoto> => {
  let base64Data: string;
  // "hybrid" will detect mobile - iOS or Android
  if (isPlatform('hybrid')) {
    const file = await Filesystem.readFile({
      path: photo.path!,
    });
    base64Data = file.data;
  } else {
    // Fetch the photo, read as a blob, then convert to base64 format
    const response = await fetch(photo.webPath!);
    const blob = await response.blob();
    base64Data = (await convertBlobToBase64(blob)) as string;
  }
  const savedFile = await Filesystem.writeFile({
    path: fileName,
    data: base64Data,
    directory: Directory.Data,
  });

  if (isPlatform('hybrid')) {
    // Display the new image by rewriting the 'file://' path to HTTP
    // Details: https://ionicframework.com/docs/building/webview#file-protocol
    return {
      filepath: savedFile.uri,
      webviewPath: Capacitor.convertFileSrc(savedFile.uri),
    };
  } else {
    // Use webPath to display the new image instead of base64 since it's
    // already loaded into memory
    return {
      filepath: fileName,
      webviewPath: photo.webPath,
    };
  }
};

        接下来,在loadSaved函数中添加一点新的逻辑。在移动设备上,我们可以直接指向 Filesystem 上的每个照片文件并自动显示它们。然而,在网络上,我们必须将文件系统中的每个图像读取为 base64 格式。这是因为文件系统 API 在底层使用了IndexedDB。更新loadSaved函数:

const loadSaved = async () => {
  const photoList = await Storage.get({ key: PHOTO_STORAGE });
  const photosInStorage = photoList.value ? JSON.parse(photoList.value) : [];

  // If running on the web...
  if (!isPlatform('hybrid')) {
    for (const photo of photosInStorage) {
      const file = await Filesystem.readFile({
        path: photo.filepath,
        directory: Directory.Data,
      });
      // Web platform only: Load the photo as base64 data
      photo.webviewPath = `data:image/jpeg;base64,${file.data}`;
    }
  }

  photos.value = photosInStorage;
};

        我们的照片库现在包含一个可在 Web、Android 和 iOS 上运行的代码库。接下来,我们将应用程序部署到设备。

八、部署到 iOS 和 Android 

        由于我们在首次创建 Capacitor 时将其添加到我们的项目中,因此在照片库应用程序在我们的设备上之前只剩下几个步骤! 

提示

请记住,您可以在此处找到此应用程序的完整源代码。

1、安装Capacitor 

        Capacitor 是 Ionic 的官方应用运行时,可以轻松地将 Web 应用部署到 iOS、Android 等原生平台。如果您过去使用过 Cordova,请考虑在此处阅读更多关于差异的信息。

        完成 Ionic 项目的全新构建,修复它报告的所有错误:

ionic build

        接下来,创建 iOS 和 Android 项目: 

$ ionic cap add ios
$ ionic cap add android

        项目根目录下的 android 和 ios 文件夹均已创建。这些是完全独立的本机项目,应该被视为您的 Ionic 应用程序的一部分(即,将它们检入源代码控制,使用它们的本机工具对其进行编辑等)。

        每次您执行ionic build更新您的web目录(默认:)的构建(例如)时build,您都需要将这些更改复制到您的本机项目中:

ionic cap copy

        注意:对代码的本机部分进行更新(例如添加新插件)后,使用sync命令: 

ionic cap sync

注意

要构建 iOS 应用程序,您需要一台 Mac 计算机。

        Capacitor iOS 应用程序通过 Xcode(Apple 的 iOS/Mac IDE)配置和管理,依赖项由 CocoaPods 管理。在 iOS 设备上运行此应用程序之前,需要完成几个步骤。

        首先,运行 Capacitoropen命令,在 Xcode 中打开原生 iOS 项目:

ionic cap open ios

        为了使某些本机插件工作,必须配置用户权限。在我们的照片库应用程序中,这包括相机插件:iOS 在第一次Camera.getPhoto()调用后会自动显示一个模式对话框,提示用户允许应用程序使用相机。驱动这个的权限被标记为“隐私 - 相机使用”。要设置它,必须修改Info.plist文件(此处有更多详细信息)。要访问它,请单击“信息”,然后展开“自定义 iOS 目标属性”。

        Info.plist中的每个设置都有一个低级参数名称和一个高级名称。默认情况下,属性列表编辑器显示高级名称,但切换到显示原始的低级名称通常很有用。为此,请右键单击属性列表编辑器中的任意位置并切换“原始键/值”。

        添加NSCameraUsageDescription键并将值设置为描述应用程序需要使用相机的原因,例如“拍照”。权限提示打开时,会向应用程序用户显示值字段。

        按照相同的过程添加相机插件所需的其他两个键:NSPhotoLibraryAddUsageDescriptionNSPhotoLibraryUsageDescription

        接下来,单击App左侧的 Project Navigator,然后在该Signing & Capabilities部分中选择您的开发团队。

        有了适当的权限并选择了开发团队,我们就可以在真实设备上试用该应用程序了!将 iOS 设备连接到您的 Mac 计算机,选择它(对我来说是App -> Matthew’s iPhone)然后单击“构建”按钮在您的设备上构建、安装和启动应用程序:

        点击照片库选项卡上的相机按钮后,将显示权限提示。点击确定,然后使用相机拍照。之后,照片在应用程序中显示!

        Capacitor Android 应用程序通过 Android Studio 进行配置和管理。在 Android 设备上运行此应用程序之前,需要完成几个步骤。

        首先,运行 Capacitor open命令,在 Android Studio 中打开原生 Android 项目:

ionic cap open android

        与 iOS 类似,我们必须启用正确的权限才能使用相机。在AndroidManifest.xml文件中配置这些。Android Studio 可能会自动打开此文件,但如果没有,请在android/app/src/main/.

        滚动到该Permissions部分并确保包含以下条目: 

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

        保存文件。有了适当的权限,我们就可以在真实设备上试用该应用程序了!将 Android 设备连接到您的计算机。在 Android Studio 中,单击“运行”按钮,选择附加的 Android 设备,然后单击“确定”在您的设备上构建、安装和启动应用程序。

        再次点击照片库选项卡上的相机按钮后,应显示权限提示。点击确定,然后使用相机拍照。之后,照片应该出现在应用程序中。 

至此,一个完整的app项目已经完成。 

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西山水壶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值