跳过主要内容
教程

使用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 上发布应用,在 Google Play Console 中注册以在 Android 上发布应用。

使用 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__

npx cap copy

Now, your app will automatically reload and show changes when you update your Vue app.

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

安装新插件后,运行命令并将应用重新部署到您的设备: sync 接下来,您可以使应用在 iOS 和 Android 上感觉更像原生应用,使用 __CAPGO_KEEP_0__ 导航和过渡,修复常见的 iOS 布局问题,例如水平溢出或裁切安全区域。

npx cap sync

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

Native-feeling UI with Capgo Native Navigation and Transitions

Ionic 来构建跨平台应用,但将其与 Vue 集成起来是hacky的,并且很少值得一试,尤其是当您已经有 __CAPGO_KEEP_0__ Tailwind CSS.

为了在 Vue + Capacitor 应用中实现原生移动体验,使用 Capgo 插件代替仅限 Web 的 UI 套件,如 Konsta 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-page中: cap-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 iOS contentInsetnever context

In 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.

In 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将修复直接发送给用户,而不是等待几天的应用商店审批。用户在后台接收更新,而原生变化仍在正常审批路径中。

来自Martin的人性化支持

立即开始

最新博客文章

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