跳过主要内容
教程

使用 Angular 和 Capacitor 构建移动应用

了解如何使用 Angular、Capacitor 和 Capgo Native Navigation、Transitions 和 iOS 布局最佳实践创建一个移动应用。

文章来源

马丁·多纳迪厄

作者

瓦莱里亚

审阅者

乔丹

编辑

Building Mobile Apps with Angular and Capacitor

在本教程中,我们将从新建一个 Angular 应用开始 Angular app and transition into the native mobile app realm using Capacitor. You can also add Capgo Native Navigation and Transitions for a native mobile feel, and use tailwind-capacitor for safe areas.

Capacitor allows you to easily convert your Angular web application into a native mobile app without requiring significant modifications or learning a new skill like React Native.

仅需几步,绝大多数 Angular 应用都可以转换为移动应用

本教程将指导您完成整个过程,首先使用新Angular应用,然后将Capacitor引入到原生移动应用的领域。您还可以使用Capgo Native Navigation, Transitions, 和tailwind-capacitor来安全区域。

Capacitor

__CAPGO_KEEP_0__是游戏改变者!您可以轻松将其整合到任何Web项目中,它将您的应用包装在原生Webview中,生成原生Xcode和Android Studio项目。另外,它的插件提供了访问原生设备功能的JS桥,如摄像头。

使用Capacitor,您可以获得一个非常棒的原生移动应用,无需复杂的设置或陡峭的学习曲线。它的API和流线化功能使其成为轻松整合到您的项目的好选择。相信我,您将惊叹于如何轻松地使用Capacitor实现一个功能齐全的原生应用。

准备您的Angular应用

要创建一个新的Angular应用,请运行以下命令:

ng new my-app
cd my-app

选择“Angular”时会提示您选择Angular版本。

为了创建一个原生移动应用,我们需要导出我们的项目。因此,让我们在我们的 package.json 中添加一个简单的脚本,用于构建和复制Angular项目: export of our project.

{
  "scripts": {
    // ...
    "build": "ng build --prod"
  }
}

After执行命令后 build,您应该能够在项目根目录看到一个新的 dist 文件夹。

This folder will be used by Capacitor later on, but for now, we must set it up correctly.

在您的Angular应用中添加Capacitor

将任何Web应用程序打包到原生移动容器中,我们必须遵循几个初始步骤,但之后只需执行一个 sync 命令。

首先,我们可以将Capacitor作为开发依赖项安装,然后在项目中设置它。在设置过程中,您可以按“回车”键以接受名称和包ID的默认值。 Capacitor CLI 最后,我们可以添加平台,Capacitor将在项目根目录创建每个平台的文件夹:

命令

最后,我们可以添加平台,Capacitor会在项目根目录为每个平台创建文件夹:

# Install the Capacitor CLI locally
npm install -D @capacitor/cli

# Initialize Capacitor in your Angular project
npx cap init

# Install the required packages
npm install @capacitor/core @capacitor/ios @capacitor/android

# Add the native platforms
npx cap add ios
npx cap add android

到目前为止,您应该能够观察到新的 ios 和 context android

context

文件夹在您的Angular项目中。 这些是真正的本机项目!要访问Android项目,必须安装 Xcode.

. capacitor.配置文件 在您的项目中,包含一些基本的Capacitor设置,这些设置在同步过程中会被使用。您需要注意的是 webDir指向您的构建命令的结果。目前,这个路径是不准确的。

为了解决这个问题,请打开 capacitor.配置文件 文件并更新 webDir:

{
  "appId": "com.example.app",
  "appName": "my-app",
  "webDir": "dist"
}

您可以通过执行以下命令来尝试它

npm run build
npx cap sync

第一个命令 npm run build 将仅仅构建您的Angular项目并复制静态构建,而第二个命令 npx cap sync 将同步所有的webcode到native平台的正确位置,以便它们可以在应用中显示。

此外,同步命令可能会更新native平台并安装插件,当您安装新的 Capacitor 插件 是时候再次运行了 npx cap sync again.

构建和部署原生应用

为了开发 iOS 应用,你需要安装

Xcode Xcode Android Studio 此外,如果你打算在应用商店上发布你的应用,你需要在 iOS 上注册 Apple Developer Program,和在 Android 上注册 Google Play Console。 如果你是新手,想要进行原生移动开发,你可以使用 __CAPGO_KEEP_0__ __CAPGO_KEEP_1__ 来轻松打开两个原生项目:

如果您是新手,想开始原生移动开发,可以使用Capacitor CLI轻松打开原生项目。

npx cap open ios
npx cap open android

__CAPGO_KEEP_1__

android-studio-run

在 Xcode 中,您需要设置您的签名账户才能将应用部署到真实设备,而不是仅仅是模拟器。如果您之前没有这样做过,Xcode 将指导您完成此过程(但请再次注意,您必须注册为开发者)。随后,您可以简单地点击播放以在连接的设备上运行应用,您可以在顶部选择设备。以下是一个示例:

xcode-run

恭喜您!您已经成功将 Angular 网站应用部署到移动设备。以下是一个示例:

angular-mobile-app

但是,请等一下,还有更快的方法可以在开发期间完成此操作……

Capacitor 实时重载

到目前为止,您可能已经习惯了所有现代框架中的热重载功能,好消息是您可以在移动设备上实现相同的功能 在移动设备上 仅需最少的努力!

启用对您的本地托管应用的访问,使用实时重载 在您的网络上 通过让Capacitor应用从特定的URL加载内容。

第一步是确定您的本地IP地址。如果您使用Mac,可以通过在终端中运行以下命令来查找此信息:

ipconfig getifaddr en0

在Windows上运行:

ipconfig

然后查找IPv4地址。

我们可以通过在文件中添加另一个条目来指示Capacitor从服务器直接加载应用程序: capacitor.config.ts 请务必使用

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.app',
  appName: 'my-app',
  webDir: 'dist',
  bundledWebRuntime: false,
  server: {
    url: 'http://192.168.x.xx:4200',
    cleartext: true
  }
};

export default config;

正确的IP和端口 ,我在本例中使用了默认的Angular端口。现在,我们可以将这些更改应用到我们的本机项目中:

命令与

npx cap copy

类似 copy 命令与 sync,但只会 拷贝到 web 文件夹中的修改 和配置文件,

而不更新原生项目。 应用将自动重新加载 应用程序将自动重新加载

并显示更改! 请记住

Note that you should use the correct IP and port in your configuration. The code block above shows the default Angular port for demonstration purposes.

Using Capacitor Plugins

Let’s take a look at how to use a Capacitor plugin in action, which we’ve mentioned a few times before. To do this, we can install a fairly simple plugin by running:

npm i @capacitor/share

请注意,您应该在配置文件中使用正确的 IP 和端口。上面的 __CAPGO_KEEP_0__ 块显示了示例用途的默认 Angular 端口。 分享插件, 不过它仍然会弹出原生分享对话框!为了实现这一点,我们现在只需导入包并从我们的应用中调用相应的 share() 函数,所以让我们改变 src/app/app.component.ts 到如下内容:

import { Component } from '@angular/core';
import { Share } from '@capacitor/share';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'my-app';

  async share() {
    await Share.share({
      title: 'Open Youtube',
      text: 'Check new video on youtube',
      url: 'https://www.youtube.com',
      dialogTitle: 'Share with friends'
    });
  }
}

如前所述,当安装新插件时,我们需要执行同步操作,然后重新部署应用到设备上。要实现这一点,请运行以下命令:

npx cap sync

点击按钮后,您可以亲眼目睹美丽的原生分享对话框!

接下来,您可以让应用在 iOS 和 Android 上感觉更原生,使用 Capgo 导航和过渡,并修复常见的 iOS 布局问题,例如水平溢出或裁切安全区域。

原生感知 UI 使用 Capgo 原生导航和过渡

我已经为年 Ionic 多年来使用它来构建跨平台应用,但将其与 Angular 集成起来是很hacky的,而且通常不值得,当您已经有 Tailwind CSS.

在 Angular + Capacitor 应用中,为了获得原生移动体验,使用 Capgo 插件代替仅限 Web 的 UI 套件,如 Konsta UI:

  • @capgo/capacitor原生导航 —— 原生导航栏、Liquid Glass iOS tab栏和 Android 模糊 tab栏样式。您的 Angular 路由器保留路由状态;插件拥有原生浏览器。
  • @capgo/capacitor-转换 —— 在 WebView层中实现Ionic风格的页面过渡和iOS边缘滑动返回,且不采用Ionic UI。

安装两者:

bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync

配置原生导航以使用 CSS inset 模式,使 Web 内容尊严原生栏:

import { NativeNavigation } from '@capgo/capacitor-native-navigation';

await NativeNavigation.configure({
  contentInsetMode: 'css',
  animationDuration: 360,
  glass: {
    effect: 'liquidGlass',
  },
});

渲染 Liquid Glass tab栏(iOS使用系统渲染;Android使用模糊 WebView 背景):

import { inject } from '@angular/core';
import { Router } from '@angular/router';

const router = inject(Router);

await NativeNavigation.setTabbar({
  selectedId: 'home',
  labelVisibilityMode: 'labeled',
  icons: true,
  colors: { dynamic: true },
  tabs: [
    { id: 'home', title: 'Home', icon: { svg: '...' } },
    { id: 'settings', title: 'Settings', icon: { svg: '...' } },
  ],
});

await NativeNavigation.addListener('tabSelect', ({ id }) => {
  router.navigate([`/${id}`]);
});

Add native page transitions in your app shell:

```typescript
// app.component.ts
import { Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { Router } from '@angular/router';
import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions';

initTransitions({ platform: 'auto' });

@Component({
  selector: 'app-root',
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `
    <cap-router-outlet #outlet platform="auto" swipe-gesture="auto">
      <router-outlet></router-outlet>
    </cap-router-outlet>
  `,
})
export class AppComponent implements AfterViewInit {
  @ViewChild('outlet') outlet?: ElementRef<HTMLElement>;

  constructor(private router: Router) {}

  ngAfterViewInit() {
    if (this.outlet?.nativeElement) {
      setupRouterOutlet(this.outlet.nativeElement, { platform: 'auto', swipeGesture: 'auto' });
    }
  }

  openSettings() {
    setDirection('forward');
    this.router.navigate(['/settings']);
  }
}

将路由页面包裹在 cap-router-outlet, cap-page中,并将 cap-content中调用 setDirection('forward') 或 setDirection('back') 在导航之前不要重复网页头部或底部。

查看完整指南: 使用@capgo/capacitor-原生导航 和 使用@capgo/capacitor-过渡.

安全区域使用Tailwind

在Tailwind CSS中使用设备安全区域 使用@capgo/tailwind-capacitor (发布于 tailwind-capacitor 在npm上。它提供 safe-areas Capacitor友好的Tailwind插件:

bun add -D tailwind-capacitor

In src/styles.css:

@import 'tailwindcss';
@plugin "@capgo/tailwind-capacitor/platform";
@plugin "@capgo/tailwind-capacitor/safe-areas";

使用 pt-safe, pb-safe, 和 px-safe 而不是 env(safe-area-inset-*) 手动添加 在GitHub上提交一个PR.

在__CAPGO_KEEP_0__上打开一个PR

修复iOS布局问题(视口、安全区域和水平溢出) overflow-x: hidden 如果内容在iOS上被裁剪、偏移或水平滚动,请尝试

或调整视口标签通常无法解决问题。按照以下顺序检查这些问题。

In src/index.html确保视口元标签正确应用于页面上 <head>:

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />

iOS安全区域只需从一个根包装器中处理

创建一个单一的应用程序外壳并在其中应用安全区域填充 — 不在多个嵌套组件中:

html,
body,
app-root {
  width: 100%;
  min-height: 100%;
  margin: 0;
  padding: 0;
  overflow-x: hidden;
}

* {
  box-sizing: border-box;
}

.app-shell {
  min-height: 100dvh;
  width: 100%;
  padding-top: env(safe-area-inset-top);
  padding-right: env(safe-area-inset-right);
  padding-bottom: env(safe-area-inset-bottom);
  padding-left: env(safe-area-inset-left);
}

将所有页面内容包装在 .app-shell. 在头部、模态对话框和布局包装器中重复的安全区域填充通常会使UI看起来被裁剪或过大。

使用 @capgo/Tailwind-capacitor,您可以用类似于 pt-safe pb-safe px-safe 的工具表达相同的填充。

设置Capacitor iOS contentInset 到 never 第一个

在 capacitor.config.ts, 优先使用原生 inset 并让 CSS (或 Native Navigation) 来控制安全区域: contentInsetMode: 'css')

const config: CapacitorConfig = {
  appId: 'com.example.myapp',
  appName: 'my-app',
  webDir: 'www',
  ios: {
    contentInset: 'never',
  },
};

混合 Capacitor 自动内容 inset 与 CSS env(safe-area-inset-*) padding 是双倍间距的常见原因。

找到真正溢出的元素

通常的凶手是使用 100vw, Tailwind w-screen, 固定像素宽度或较大的 min-width.

在 Safari Web Inspector 中,运行:

[...document.querySelectorAll('*')]
  .filter(el => el.scrollWidth > document.documentElement.clientWidth)
  .map(el => ({
    el,
    tag: el.tagName,
    class: el.className,
    scrollWidth: el.scrollWidth,
    clientWidth: document.documentElement.clientWidth,
  }));

当可能时,使用 w-screen 代替 w-full ,尽可能多地解决水平溢出问题 100vw / w-screen,避免了安全区域的重复填充或固定宽度的容器 —— 不是来自 viewport meta 标签本身。

结论

Capacitor 是基于现有 web 项目构建原生应用的优秀选择,提供了一个简单的方式来共享 code 并保持一致的 UI。

并且通过添加 Capgo,即使是添加实时更新到您的应用中,也能确保您的用户始终可以访问最新的功能和 bug 修复。

如果您想学习如何将 Capgo 添加到您的 Angular 应用中,请查看下一篇文章:

继续阅读 Building Mobile Apps with Angular 和 Capacitor

如果您正在使用 Building Mobile Apps with Angular 和 Capacitor 来规划原生媒体和界面行为,连接它与 使用 @capgo/capacitor-live-activities 为使用@capgo/capacitor-live-activities的原生能力 @capgo/capacitor-live-activities 在@capgo/capacitor-live-activities的实现细节中 使用@capgo/capacitor-video-player 为使用@capgo/capacitor-video-player的原生能力 @capgo/capacitor-视频播放器 在@capgo/capacitor-video-player的实现细节中,并且 使用@capgo/capacitor-native-navigation 为使用@capgo/capacitor-native-navigation的原生能力

为Capacitor应用提供即时更新

当有一个web层bug在live状态时,通过Capgo将修复直接推送给用户,而不是等待几天的app store审批。用户在后台接收更新,而原生变化仍然在正常审批路径中。

最新博客

Capgo 为您提供创建真正专业的移动应用所需的最佳见解。