跳过主要内容
教程

使用Vue和Capacitor构建移动应用

学习如何使用Vue、Capacitor创建移动应用,并可选地增强Capgo原生导航、过渡效果和iOS布局最佳实践

文章来源

马丁·多纳迪厄

作者

瓦莱里亚

审阅者

乔丹

编辑

使用Vue和Capacitor构建移动应用

In本教程中,我们将指导您将 Vue 网页应用程序转换为使用 Capacitor 的原生移动应用程序。您还可以添加 Capgo 原生导航和过渡,使用 tailwind-capacitor 来安全区域。

关于 Capacitor

Capacitor 是一个颠覆性的工具,允许您轻松将其集成到任何 web 项目中,并将应用程序转换为原生移动应用程序。它生成原生 Xcode 和 Android Studio 项目,并通过 JavaScript 桥提供对原生设备功能(如摄像头)的访问。

准备 Vue 应用程序

首先,通过运行以下命令创建一个新 Vue 应用程序:

vue create my-app
cd my-app
npm install

要为原生移动部署准备 Vue 应用程序,需要导出您的项目。将一个脚本添加到您的 package.json 文件中,用于构建和复制 Vue 项目:

{
  "scripts": {
    // ...
    "build": "vue-cli-service build"
  }
}

运行命令后,您应该在项目根目录中看到一个新 build 文件夹。这将由 __CAPGO_KEEP_0__ 后续使用。 dist 将 Capacitor 添加到 Vue 应用程序中

将 Capacitor 添加到 Vue 应用程序中

将您的 Vue 网页应用转换为原生移动容器,请遵循以下步骤:

  1. 安装 Capacitor 和 CLI 作为开发依赖项,并在您的项目中设置它们。接受名称和包 ID 的默认值。

  2. 安装核心包和 iOS 和 Android 平台的相关包。

  3. 添加平台,Capacitor 将在您的项目根目录创建每个平台的文件夹:

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

# Initialize Capacitor in your Vue 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

您现在应该看到新的 iOSandroid 文件夹在您的 Vue 项目中。

更新 capacitor.config.json 文件以指向 webDir 执行构建命令后得到的结果:

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

现在,您可以构建 Vue 项目并同步它与 Capacitor:

npm run build
npx cap sync

构建和部署原生应用

为了开发 iOS 应用,您需要安装 Xcode,开发 Android 应用需要安装 Android Studio。另外,您还需要在 Apple Developer Program 中注册以便于 iOS 应用在 App Store 上发布,同样在 Google Play Console 中注册以便于 Android 应用在 Google Play Store 上发布。

使用 Capacitor CLI 打开两款原生项目:

npx cap open ios
npx cap open android

使用 Android Studio 或 Xcode 将应用部署到连接的设备上。

Capacitor Live Reload

通过让 Capacitor 应用从您的网络上的特定 URL 加载内容来在移动设备上启用实时重载。

找到您的本地 IP 地址并更新文件中的 IP 和端口: 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:8080',
    cleartext: true
  }
};

export default config;

__CAPGO_KEEP_0__ Live Reload

npx cap copy

现在,应用程序将自动重新加载并显示更改,当您更新 Vue 应用程序时。

使用Capacitor插件

安装一个Capacitor插件,如分享插件,并在 Vue 应用程序中使用它:

npm i @capacitor/share

导入包并在应用程序中调用函数: share() 安装新插件后,运行命令并将应用程序重新部署到设备:

<template>
  <div>
    <h1>Welcome to Vue 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>

接下来,您可以使应用程序在 iOS 和 Android 上感觉更像原生应用程序,使用__CAPGO_KEEP_0__导航和过渡,并修复常见的 iOS 布局问题,导致水平溢出或裁剪安全区域。 sync 原生感觉的UI使用__CAPGO_KEEP_0__原生导航和过渡

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.

Native-feeling UI with Capgo Native Navigation and Transitions

来构建跨平台应用程序,但将其与 Vue 集成是hacky的,并且在您已经有它时很少值得 Capacitor Capgo Tailwind CSS.

在 Vue + Capacitor 应用中,为了实现原生移动体验,使用 Capgo 插件代替像 Konsta UI 这样的仅限 Web UI 套件:

  • @capgo/capacitor-native-navigation —— 原生导航栏、Liquid Glass iOS tab栏和 Android 模糊 tab栏样式。您的 Vue 路由器保持路由状态,插件拥有原生浏览器。
  • @capgo/capacitor-transitions —— 在 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背景):

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-pagecap-content或呼叫 setDirection('forward')setDirection('back') 查看完整指南:

使用@__CAPGO_KEEP_0__/__CAPGO_KEEP_1__-原生导航 Using @capgo/capacitor-native-navigation 使用@__CAPGO_KEEP_0__/__CAPGO_KEEP_1__-过渡 Using @capgo/capacitor-transitions.

在Tailwind CSS中,使用

@__CAPGO_KEEP_0__/tailwind-__CAPGO_KEEP_1__ @capgo/tailwind-capacitor 在__CAPGO_KEEP_0__上。它提供 tailwind-capacitor on npm). It provides safe-areas 工具和其他 Capacitor 友好的 Tailwind 插件:

bun add -D tailwind-capacitor

In src/assets/main.css:

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

使用工具,如 pt-safe, pb-safe, 和 px-safe 而不是手动添加 env(safe-area-inset-*) 通过手动添加。该项目正在积极开发中 — 如果您的 Vue 设置中缺少某些内容,请 open a PR on GitHub.

如果内容看起来被裁切、偏移或水平滚动在 iOS 上,仅添加或调整视口标签通常无法解决问题。按照以下顺序检查这些问题。

确保视口元标签正确应用 overflow-x: hidden

添加视口元标签

Add the viewport meta tag in index.html inside <head>:

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

从根组件中只处理 iOS 安全区域

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

html,
body,
#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. 在头部、模态对话框和布局包装器中重复的安全区域填充通常会使 UI 看起来被裁剪或过大。

使用 @capgo/tailwind-capacitor,您可以用工具类来表达相同的填充。 pt-safe pb-safe px-safe 设置

Capacitor contentInset 为 iOS never 设为"首选"

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

const config: CapacitorConfig = {
  appId: 'com.example.myapp',
  appName: 'my-app',
  webDir: 'dist',
  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 项目构建原生应用的绝佳选择。通过添加 Capgo,甚至更容易将实时更新添加到您的应用中,从而确保您的用户始终可以访问最新的功能和 bug 修复。

了解 Capgo 如何帮助您快速构建更好的应用 立即注册 今天。

继续 Building Mobile Apps with Vue 和 Capacitor

如果您正在使用 Building Mobile Apps with Vue 和 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-video-player 为@capgo/capacitor-video-player的实现细节,并且 使用@capgo/capacitor-native-navigation 为使用@capgo/capacitor-native-navigation的原生功能

实时更新Capacitor应用

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

来自Martin的人类支持

立即开始

最新博客文章

Capgo gives you the best insights you need to create a truly professional mobile app.