在本教程中,我们将从一个新的 Angular 应用开始,逐步进入使用 Capacitor 的原生移动应用领域。您还可以添加 Capgo 原生导航和过渡,实现原生移动应用的感觉,并使用 tailwind-capacitor 来安全区域。
Capacitor 允许您轻松将 Angular 网络应用转换为原生移动应用,无需进行重大修改或学习新的技能,如 React Native。
With just a few simple steps, most Angular applications can be transformed into mobile apps.
This tutorial will guide you through the process, starting with a new Angular app and then incorporating Capacitor to move into the realm of native mobile apps. You can also use Capgo Native Navigation, Transitions, and tailwind-capacitor for safe areas.
关于 Capacitor
CapacitorJS 是一个革命性的工具!您可以轻松将其整合到任何 Web 项目中,它会将您的应用包装在一个原生 Webview 中,生成原生 Xcode 和 Android Studio 项目。并且,它的插件提供了对原生设备功能的访问,例如通过 JS 桥访问摄像头。
With Capacitor, you get a fantastic native mobile app without any complicated setup or steep learning curve. Its slim API and streamlined functionality make it a breeze to integrate into your project. Trust me, you’ll be amazed at how effortless it is to achieve a fully functional native app with Capacitor!
准备您的 Angular 应用
要创建一个新的 Angular 应用,请运行以下命令:
ng new my-app
cd my-app
选择“Angular”时会提示您选择 Angular 版本。
要创建一个原生移动应用,我们需要一个 export 我们的项目。因此,让我们在我们的 package.json 可以用来构建和复制Angular项目的工具:
{
"scripts": {
// ...
"build": "ng build --prod"
}
}
执行命令后 build你应该在项目根目录下看到一个新的 dist 文件夹。这个文件夹将在稍后由__CAPGO_KEEP_0__使用,但现在我们必须正确地设置它。
将Capacitor添加到Angular App中
Adding Capacitor to Your Angular App
命令就可以了。 sync 首先,我们可以将
__CAPGO_KEEP_0__ __CAPGO_KEEP_1__ Capacitor CLI 接下来,我们需要安装核心包和iOS和Android平台的相关包。
__CAPGO_KEEP_2__
最后,我们可以添加平台,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 和 android 文件夹在您的Angular项目中。
这些是真正的本机项目!
要在将来访问Android项目,必须安装 Android Studio。对于iOS,需要Mac,并应安装 Xcode.
此外,您应该找到 capacitor.config.ts Capacitor项目中的一个文件,包含一些基本的Capacitor设置,用于同步过程中。您需要注意的是 webDir, which must point to the result of your build command. Currently, it is inaccurate.
为了解决这个问题,请打开 capacitor.config.json 文件并更新 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平台的正确位置,以便在app中显示。
另外,同步命令可能会更新本机平台并安装插件,因此当您安装新插件时, Capacitor 插件 npx cap sync 需要重新运行
命令。
您可能没有注意到,您已经完成了,
所以让我们在设备上看看应用! 构建和部署本机应用 要开发iOS应用,您需要安装 Xcode ,并且要开发Android应用,您需要安装
If you’re new to native mobile development, you can use the Capacitor CLI to easily open both native projects:
npx cap open ios
npx cap open android
一旦您设置了本机项目,部署应用程序到连接设备就变得简单了。在 Android Studio 中,您只需等待所有内容准备就绪,然后就可以在不更改任何设置的情况下将应用程序部署到连接设备。以下是示例:

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

恭喜您!您已经成功将 Angular 网络应用程序部署到移动设备。以下是示例:
但请稍等,开发期间还有更快的方法……
Capacitor Live Reload
到目前为止,您可能习惯了所有现代框架都具有热重载的功能,好消息是您可以在移动设备上实现相同的功能 在移动设备上 仅需最少的努力!
启用对本地托管应用程序的访问,使用实时重载 On your network 通过让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
The copy command 与 Capacitor 类似,但它只会 synccopy over web folder 和配置中的修改,而不更新 native 项目。 您可以通过 Android Studio 或 Xcode 再次部署您的应用程序。之后,如果您在 Angular 应用程序中更改了什么 ,应用程序将自动重新加载
并显示更改! 请记住 如果您安装了新插件,如摄像头插件,它仍然需要重新构建 native 项目。这是因为 native 文件已更改,而不能在实时进行。
请注意,在您的配置中应使用正确的 IP 和端口。上面的 __CAPGO_KEEP_0__ 块显示了示例目的地的默认 Angular 端口。 使用 __CAPGO_KEEP_0__ 插件
让我们看看如何使用 code 插件的示例,之前我们提到过几次。要实现这一点,我们可以通过运行:
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
There’s nothing fancy about the 分享插件但是它仍然会弹出原生分享对话框!为了实现这一点,我们现在只需要导入包并从我们的应用中调用相应的 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
如前所述,当安装新插件时,我们需要执行同步操作,然后重新部署应用到设备上。要实现这一点,请运行以下命令:
Next, you can make the app feel more native on iOS and Android with Capgo navigation and transitions, and fix common iOS layout issues that cause horizontal overflow or cropped safe areas.
接下来,您可以让应用在 iOS 和 Android 上感觉更原生,使用 Capgo 导航和过渡,并修复常见的 iOS 布局问题,导致水平溢出或裁剪安全区域。
原生感知 UI 与 __CAPGO_KEEP_0__ 原生导航和过渡 我已经与 To 构建跨平台应用,但将其与 Angular 集成起来很hacky,并且当你已经有了它时,很少值得: 使用 Tailwind CSS.
为了在 Angular + Capacitor 应用中获得原生移动体验,使用 Capgo 插件而不是仅限Web的UI套件,如 Konsta UI:
- @capgo/capacitor-native-navigation — 原生导航栏,iOS上的Liquid Glass标签栏,Android上的模糊标签栏样式。您的Angular路由器保留路由状态;插件拥有原生浏览器。
- @capgo/capacitor-transitions — 在WebView层中实现Ionic样式页面过渡和iOS边缘滑动返回,without采用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标签栏(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-native-navigation 和 使用@capgo/capacitor-transitions.
安全区域与Tailwind
在Tailwind CSS中,使用 @capgo/tailwind-capacitor (发布于 tailwind-capacitor npm)。它提供 safe-areas utilities and other Capacitor-friendly 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-*) , open a PR on GitHub.
在 __CAPGO_KEEP_0__ 上打开一个 PR
iOS 布局问题(视口、安全区域和水平溢出) overflow-x: hidden 如果内容在 iOS 上被裁切、偏移或水平滚动,
仅添加或调整视口标签通常无法解决问题。按照以下顺序检查这些问题。
确保视口元标签已正确应用 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 首位
In 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,
}));
使用 Tailwind,替换 w-screen with w-full 当可能时。许多水平溢出问题来自 100vw / w-screen,重复的安全区域填充或固定宽度容器 —— 不是来自视口元标签本身。
结论
Capacitor 是基于现有 Web 项目构建原生应用的优秀选择,提供了一个简单的方法来共享 code 并保持一致的 UI。
并且,通过添加 Capgo”,您甚至可以更轻松地向您的应用添加实时更新,使您的用户始终能够访问最新的功能和 bug 修复。如果您想学习如何将 __CAPGO_KEEP_0__ 添加到您的 Angular 应用中,请查看下一篇文章:
继续从 Building Mobile Apps with Angular 和 Capgo 中学习
Keep going from Building Mobile Apps with Angular and Capacitor
Building Mobile Apps with Angular 和 __CAPGO_KEEP_0__ Building Mobile Apps with Angular and Capacitor __CAPGO_KEEP_0__ 使用@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-video-player 了解@capgo/capacitor-video-player的实现细节 使用@capgo/capacitor-native-navigation 为@capgo/capacitor-native-navigation提供原生能力