在本教程中,我们将首先使用 Quasar创建一个新的 Web 应用。随后,我们将学习如何使用 Capacitor 将其转化为移动应用,从而提升应用在移动端的体验。
借助 Capacitor,你可以将 Quasar Web 应用转换为移动应用,无需处理复杂的底层逻辑,也不必像使用 React Native 那样去学习一套全新的开发模式。
本教程将带你从创建一个全新的 Quasar 应用开始,随后通过引入 Capacitor 迈入原生移动应用领域。此外,你还将使用 Capgo 在几秒钟内向你的应用推送 live update。
关于 Capacitor
CapacitorJS 绝对是一款改变游戏规则的产品!你可以轻松地将其集成到任何 Web 项目中,它会将你的应用封装进原生 WebView,并为你生成原生的 Xcode 和 Android Studio 项目。此外,它的插件还能通过 JS bridge 调用摄像头等原生设备功能。
借助 Capacitor,你无需复杂配置,也不用面对陡峭的学习曲线,就能获得出色的原生移动应用。其轻量的 API 和精简的功能让集成变得轻而易举。相信我,你会惊讶于用 Capacitor 实现功能完备的原生 App 竟如此简单!
准备你的 Quasar 应用
要创建一个新的 Quasar 应用,请运行以下命令:
npm init quasar

选择 “App with Quasar CLI” 选项,然后选择 “Quasar v2”。
为了创建一个原生移动应用,我们需要一个 export 项目。因此,让我们在 package.json 中添加一个简单的脚本,用于构建并复制 Quasar 项目:
{
"scripts": {
// ...
"build": "quasar build"
}
}
执行完该命令 generate后,你应该能在 dist 项目根目录下看到一个新的文件夹。
Capacitor 稍后会用到这个文件夹,但现在我们需要正确配置它。
将 Capacitor 添加到你的 Quasar App
要将任何 Web App 打包进原生移动容器,我们需要先完成几个初始步骤,但之后只需执行一条 sync 命令。
首先,我们可以安装 Capacitor CLI 将其作为开发依赖安装,然后在我们的项目中配置。设置过程中,按“enter”即可接受 name 和 bundle ID 的默认值。
接下来,我们需要安装核心包以及 iOS 和 Android 平台的相关包。
最后,我们可以添加平台,Capacitor 会在项目根目录下为每个平台创建文件夹:
# Install the Capacitor CLI locally
npm install -D @capacitor/cli
# Initialize Capacitor in your Quasar 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 在你的 Quasar 项目中创建文件夹。
这些都是真正的原生项目!
之后要访问 Android 项目,你需要安装 Android Studio 中的错误日志. 对于 iOS,你需要一台 Mac,并安装 Xcode 的 Mac.
此外,你还需要找到 capacitor.config.ts 文件,其中包含同步过程中用到的一些基础 Capacitor 设置。你唯一需要注意的是 webDir,它必须指向 build 命令的输出目录。目前该配置不正确。
要修复此问题,请打开 capacitor.config.json 文件并更新 webDir:
{
"appId": "com.example.app",
"appName": "my-app",
"webDir": "dist"
}
你可以执行以下命令来试用:
npm run generate
npx cap sync
第一条命令 npm run generate 只需构建你的 Quasar 项目并复制静态构建文件,而第二个命令 npx cap sync 会将所有 Web code 同步到原生平台的对应位置,以便在 App 中显示。
此外,sync 命令可能会更新原生平台并安装插件,因此当你安装新的 Capacitor 插件 是时候运行 npx cap sync 再次尝试。
不知不觉中,你已经完成了,让我们在设备上看看 App 吧!
构建并部署原生应用
若要开发 iOS 应用,你需要拥有 Xcode 的 Mac 好,而开发 Android 应用则需要安装 Android Studio 中的错误日志 已安装。此外,如果你计划在应用商店发布应用,则需要加入 iOS 的 Apple Developer Program,并注册 Android 的 Google Play Console。
如果你刚接触原生移动开发,可以使用 Capacitor CLI 轻松打开这两个原生项目:
npx cap open ios
npx cap open android
原生项目配置好后,将应用部署到已连接的设备非常简单。在 Android Studio 中,只需等待一切就绪,无需更改任何设置即可将应用部署到已连接的设备。示例如下:

在 Xcode 中,你需要配置签名账户,以便将应用部署到真机,而不只是模拟器。如果你以前没操作过,Xcode 会引导你完成整个流程(但同样需要加入 Developer Program)。之后,只需点击运行,即可在顶部选中的已连接设备上运行应用。示例如下:

恭喜!你已成功将 Quasar Web 应用部署到移动设备。示例如下:
不过等等,在开发过程中其实还有一种更快捷的方法……
Capgo Live Update
Capgo Live Update 是一项让开发者无需经过传统的 App Store 提交流程,就能为移动应用部署更新的服务。这是一种快速修复 Bug 或进行小更新的便捷方式,无需等待 App Store 审核。
将 Capgo 集成到您的 Quasar 应用中非常简单,这能让您充分利用实时 Live Update 的强大功能。本指南将逐步带您完成 Capgo Live Update 的集成与实现,助您实现无缝更新。
注册并访问 Capgo Dashboard:
现在就开始注册,获取您的 API key 来上传第一个版本吧!首先 注册一个 Capgo 账号.
安装 Capgo SDK:
在命令行中,直接进入您的 Capacitor 应用根目录,运行:
npm i @capgo/capacitor-updater && npx cap sync 将插件安装到你的 Capacitor App 中。
然后将此 code 添加到您的应用中,作为 CodePush 的替代方案:
import { CapacitorUpdater } from '@capgo/capacitor-updater'
CapacitorUpdater.notifyAppReady()
这将告知原生插件安装已成功。
登录 Capgo CLOUD:
首先,使用 all apikey 使用你账户中的 apikey,通过 CLI 登录:
`npx @capgo/cli@latest login YOU_KEY`
添加您的第一个 App:
首先,我们用 CLI 在 Capgo Cloud 中创建一个应用。
npx @capgo/cli@latest app add
这个命令会使用 Capacitor 配置文件中定义的所有变量来创建应用。
上传你的第一个版本:
运行以下命令构建 code,并将其发送到 Capgo:
npx @capgo/cli@latest bundle upload`
默认情况下,版本名称将与您的 package.json 文件中的一致。
查看 Capgo 如果构建已存在。
你甚至可以用我的 移动端 sandbox app 来测试.
将 channel 设为默认:
将应用发送至 Capgo 后,您需要将 channel 设置为默认值,以便应用能够接收来自 Capgo 的更新。
npx @capgo/cli@latest channel set production -s default
配置应用以验证更新:
将此配置添加到您的主 JavaScript 文件中。
import { CapacitorUpdater } from '@capgo/capacitor-updater'
CapacitorUpdater.notifyAppReady()
然后执行 npm run build && npx cap copy 来更新你的 App。
接收 Live Update:
要让应用从 Deploy 接收 live update,你需要在设备或模拟器上运行应用。最简单的方法是用以下命令,在模拟器或连接到电脑的设备上启动本地应用。
npx cap run [ios | android]
打开应用,切到后台再打开,你应该能在 logs 中看到应用完成了更新。
恭喜!🎉 你已成功部署了第一个 Live Update。这只是 Live Updates 能做什么的开始。想了解更多,请查看完整的 Live Updates 文档.
使用 Capacitor 插件
我们来看看如何实际使用 Capacitor 插件,前面已经提过几次。为此,可以运行以下命令安装一个相当简单的插件:
npm i @capacitor/share
这个 分享插件,但它还是会弹出原生分享对话框!为此,我们现在只需导入这个 package,并调用相应的 share() 函数即可。让我们把 pages/index.vue 修改为:
<template>
<div>
<h1>Welcome to Quasar and Capacitor!</h1>
<button @click="share">Share now!</button>
</div>
</template>
<script setup lang="ts">
import { Share } from '@capacitor/share';
async function share() {
await Share.share({
title: 'Open Youtube',
text: 'Check new video on youtube',
url: 'https://www.youtube.com',
dialogTitle: 'Share with friends'
});
}
</script>
如前所述,安装新 plugin 时,我们需要执行 sync 操作,然后将应用重新部署到设备上。为此,请运行以下命令:
npx cap sync
点击按钮后,你就能看到精美的原生分享对话框弹出啦!
接下来,你可以通过 Capgo 导航和过渡效果,让应用在 iOS 和 Android 上更具原生感,并修复会导致水平溢出或安全区域被裁剪的常见 iOS 布局问题。
使用 Capgo 原生导航与过渡效果,打造原生感 UI
我多年来一直在使用 Ionic 用于构建跨平台应用,但如果你已经在使用,那么将其与 Quasar 集成会显得非常 hacky,且通常并不值得: Tailwind CSS.
若想在 Quasar + Capacitor 应用中获得原生移动端体验,请使用 Capgo 插件,而不是像 Konsta UI 这样的纯 Web UI 组件库:
- @capgo/capacitor-native-navigation — 原生导航栏、iOS 上的 Liquid Glass 标签栏,以及 Android 上的毛玻璃标签栏样式。你的 Quasar router 负责路由状态,而插件则负责原生 UI 框架。
- @capgo/capacitor-transitions — 在 WebView 层实现 Ionic 风格的页面过渡和 iOS 边缘侧滑返回,而无需采用 Ionic UI。
安装两者:
npm add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
npmx 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 背景):
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.push(`/${id}`);
});
在应用外壳中添加原生页面转场效果:
<script setup>
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions/vue';
initTransitions({ platform: 'auto' });
const router = useRouter();
const outletRef = ref(null);
onMounted(() => {
if (outletRef.value) {
setupRouterOutlet(outletRef.value, { platform: 'auto', swipeGesture: 'auto' });
}
});
const openSettings = () => {
setDirection('forward');
router.push('/settings');
};
</script>
<template>
<cap-router-outlet ref="outletRef">
<router-view />
</cap-router-outlet>
</template>
将路由页面包裹在 cap-router-outlet, cap-page,以及 cap-content,并调用 setDirection('forward') 或 setDirection('back') 导航前。当原生导航接管这些区域时,请勿重复添加 Web 页眉或页脚。
查看完整指南: 使用 @capgo/capacitor-native-navigation 以及 使用 @capgo/capacitor-transitions.
使用 Tailwind 处理安全区域
在 Tailwind CSS 中处理设备安全区域,请使用 @capgo/tailwind-capacitor (发布为 tailwind-capacitor 在 npm 上)。它提供 safe-areas 工具类和其他对 Capacitor 友好的 Tailwind 插件:
npm add -D tailwind-capacitor
在 src/css/app.scss:
@import 'tailwindcss';
@plugin "@capgo/tailwind-capacitor/platform";
@plugin "@capgo/tailwind-capacitor/safe-areas";
使用以下工具类,例如 pt-safe, pb-safe,以及 px-safe 而不是零散地 env(safe-area-inset-*) 手动完成。项目正在积极开发中——如果你的 Quasar 配置缺少某些内容, 请在 GitHub 上提交 PR.
修复 iOS 布局问题(视口、安全区域与水平溢出)
如果 iOS 上的内容看起来被裁剪、偏移或可水平滚动,仅靠添加更多 overflow-x: hidden 或单独调整 viewport 标签通常无法解决问题。请按顺序进行以下检查。
确保 viewport meta 标签已正确应用
在 index.html (或您的 Quasar HTML 模板),在其中设置 viewport meta 标签 <head>:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
只用一个根容器处理 iOS 安全区域
创建一个统一的 app shell,并在其中应用 safe area 内边距,而不是在多个嵌套组件中:
html,
body,
#q-app {
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。在 header、modal 和 layout wrapper 中重复设置 safe-area padding 往往会让 UI 看起来被裁剪或过大。
使用 @capgo/tailwind-capacitor,你可以使用如下 utility 类来实现相同的 padding pt-safe pb-safe px-safe 在这个单一 shell 上。
设置 Capacitor iOS contentInset 改为 never 首先
在 capacitor.config.ts,建议禁用 native inset,让 CSS(或 Native Navigation 的 contentInsetMode: 'css')来管理安全区域:
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'dist/spa',
ios: {
contentInset: 'never',
},
};
将 Capacitor 的自动 content 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 配合 w-full 尽可能避免。许多水平溢出问题都来自 100vw / w-screen重复的 safe-area 内边距或固定宽度容器,而不是 viewport meta 标签本身。
总结
Capacitor 是基于现有 Web 项目构建原生应用的绝佳选择,它提供了一种简单的方式来共享 code 并保持一致的 UI。
此外,通过引入 Capgo,为应用添加 Live Updates 变得更加简单,确保用户始终能获得最新功能和 Bug 修复。
如果您想了解如何在 Next.js 应用中加入 Capgo,请看下一篇文章:
继续阅读《使用 live updates、Quasar 和 Capacitor 创建移动应用》
如果你正在使用 使用 live updates、Quasar 和 Capacitor 创建移动应用。 要规划原生插件工作,请将其与 Capgo 插件目录 查看 Capgo 插件目录中的产品工作流, Capgo 提供的 Capacitor 插件 查看由 Capgo 提供的 Capacitor 插件中的实现细节, 添加或更新插件 查看添加或更新插件中的实现细节, Ionic Enterprise 插件替代方案 查看 Ionic Enterprise 插件替代方案中的产品工作流,以及 Capgo Native Build 查看 Capgo Native Builds 中的产品工作流。