鴻蒙學習實戰之路-Web 頁面適配最佳實踐

Web 頁面適配是 HarmonyOS 應用開發中常見的需求,本文將介紹如何在鴻蒙應用中實現 Web 頁面的最佳適配方案,包括基礎使用、響應式佈局、視頻播放適配、深色模式適配等內容。

關於本文

自己學習並使用 HarmonyOS Web 組件的記錄,旨在幫助小夥伴們少走彎路

華為開發者聯盟-Web 組件文檔永遠是你的好夥伴,請收藏!

  • 本文並不能代替官方文檔,所有的內容也都是基於官方文檔+自己嘗試的記錄。
  • 基本所有章節基本都會附上對應的文檔鏈接,強烈建議你點看看看
  • 所有結合代碼操作的部分,建議自己動手嘗試一下

代碼測試環境

環境/工具

版本/説明

DevEco Studio

5.0.3.400

HarmonyOS SDK

API Version 12

Node.js

18.19.0

測試設備

HarmonyOS 4.0+ 模擬器

1. 概述

在 HarmonyOS 應用開發中,Web 組件是實現 Web 頁面加載和交互的核心組件。通過 Web 組件,開發者可以在鴻蒙應用中無縫集成 Web 內容,實現豐富的跨平台體驗。Web 頁面適配是確保 Web 內容在不同設備、不同系統主題下都能良好展示的關鍵技術。

1.1 Web 組件基本概念

Web 組件(WebView)是 HarmonyOS 提供的用於加載和顯示 Web 頁面的組件,它基於開源的 Chromium 內核,支持現代 Web 標準。

1.2 Web 頁面適配的應用場景

  • 內容展示類應用:需要展示大量 Web 內容的新聞、資訊類應用
  • 電商應用:商品詳情頁、活動頁面等需要靈活定製的內容
  • 教育應用:在線課程、學習資料等需要豐富交互的內容
  • 企業應用:內部系統、OA 辦公等需要快速遷移的 Web 應用

2. Web 組件基礎使用

2.1 配置 Web 組件依賴

在項目的module.json5文件中添加網絡訪問權限:

{
  module: {
    // ...其他配置
    abilities: [
      {
        // ...其他配置
        skills: [
          {
            // ...其他配置
          },
        ],
      },
    ],
    requestPermissions: [
      {
        name: "ohos.permission.INTERNET",
      },
    ],
  },
}

2.2 基本的 Web 組件使用

import { webview } from '@kit.ArkWeb';
import { Column, Text, TitleBar, Web, Flex, Image } from '@kit.ArkUI';

@Component
export struct WebPage {
  // 創建Web控制器
  private webviewController: webview.WebviewController = new webview.WebviewController();
  // Web頁面加載狀態
  @State loadingProgress: number = 0;
  // 頁面標題
  @State pageTitle: string = '加載中...';

  build() {
    Column() {
      // 標題欄
      TitleBar() {
        Text(this.pageTitle).fontSize(20).fontWeight(500);
      }
      .backgroundColor($r('app.color.primary'))
      .height(56)

      // 加載進度條
      if (this.loadingProgress < 100) {
        Flex() {
          Flex()
            .width(`${this.loadingProgress}%`)
            .height(3)
            .backgroundColor($r('app.color.primary'))
        }
        .width('100%')
        .height(3)
        .backgroundColor('#E0E0E0')
      }

      // Web組件
      Web({
        src: 'https://developer.huawei.com/consumer/cn/',
        controller: this.webviewController
      })
      .width('100%')
      .height('100%')
      // 加載進度變化回調
      .onProgressChange((event) => {
        this.loadingProgress = event.newProgress;
      })
      // 頁面標題變化回調
      .onTitleReceive((event) => {
        this.pageTitle = event.title;
      })
      // 頁面加載完成回調
      .onPageEnd(() => {
        console.info('Web頁面加載完成');
      })
    }
    .width('100%')
    .height('100%')
  }
}

3. 頁面資源管理

3.1 本地 Web 頁面資源

將 Web 頁面資源放置在項目的src/main/resources/rawfile目錄下:

src/main/resources/
└── rawfile/
    └── my_web_page/
        ├── index.html
        ├── css/
        │   └── style.css
        ├── js/
        │   └── script.js
        └── images/
            └── logo.png

3.2 加載本地 Web 頁面

Web({
  src: $rawfile("my_web_page/index.html"),
  controller: this.webviewController,
})
  .width("100%")
  .height("100%");

3.3 本地資源路徑處理

在 HTML 文件中,使用相對路徑引用本地資源:

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>本地Web頁面</title>
    <link rel="stylesheet" href="css/style.css" />
  </head>
  <body>
    <div class="container">
      <img src="images/logo.png" alt="Logo" />
      <h1>歡迎使用本地Web頁面</h1>
      <p>這是一個在HarmonyOS應用中加載的本地Web頁面示例。</p>
    </div>
    <script src="js/script.js"></script>
  </body>
</html>

4. 響應式佈局適配

4.1 視口設置

在 HTML 文件的 head 標籤中設置正確的 viewport:

<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>

4.2 使用 CSS 媒體查詢

/* 基礎樣式 */
.container {
  width: 100%;
  padding: 16px;
}

/* 平板設備適配 */
@media (min-width: 768px) {
  .container {
    max-width: 720px;
    margin: 0 auto;
    padding: 24px;
  }
}

/* 桌面設備適配 */
@media (min-width: 1024px) {
  .container {
    max-width: 960px;
    padding: 32px;
  }
}

以下是不同斷點下的 Web 頁面適配效果:

斷點

效果圖

sm

md

lg

4.3 HarmonyOS 中的 Web 組件適配

在 ArkTS 中,根據不同設備類型調整 Web 組件的大小:

import { device } from '@kit.ArkUI';

@Component
export struct AdaptiveWebPage {
  private webviewController: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({
        src: 'https://developer.huawei.com/consumer/cn/',
        controller: this.webviewController
      })
      // 根據設備類型調整寬度
      .width(device.isTablet ? '80%' : '100%')
      .height('100%')
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
  }
}

4.4 常用響應式佈局模式

在 Web 開發中,常用的響應式佈局模式有:

  1. 流式佈局:使用百分比寬度,讓元素隨容器大小變化
  2. 彈性佈局:使用 Flexbox 實現靈活的一維佈局
  3. 柵格佈局:使用 CSS Grid 實現二維網格佈局
    柵格佈局(宮格佈局)是一種強大的二維佈局系統,可以將頁面劃分為多個行和列,實現複雜的佈局效果。

以下是宮格佈局的示例代碼:

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>宮格佈局示例</title>
    <style>
      /* 宮格容器 */
      .grid-container {
        display: grid;
        grid-template-columns: repeat(3, 1fr); /* 3列布局 */
        grid-template-rows: repeat(2, 100px); /* 2行佈局,每行高度100px */
        gap: 10px; /* 網格間距 */
        padding: 10px;
      }

      /* 宮格項 */
      .grid-item {
        background-color: #4caf50;
        color: white;
        text-align: center;
        padding: 20px;
        font-size: 18px;
      }
    </style>
  </head>
  <body>
    <div class="grid-container">
      <div class="grid-item">1</div>
      <div class="grid-item">2</div>
      <div class="grid-item">3</div>
      <div class="grid-item">4</div>
      <div class="grid-item">5</div>
      <div class="grid-item">6</div>
    </div>
  </body>
</html>

上述示例代碼的運行效果如下:

鴻蒙學習實戰之路-Web 頁面適配最佳實踐_webview

  1. 自適應佈局:為不同設備尺寸創建不同的佈局方案

4.5 案例:輪播佈局的響應式適配

輪播佈局(輪播圖)是 Web 開發中常用的組件之一,需要特別注意其響應式適配。輪播佈局的適配關鍵點包括:

  • 控制輪播元素的尺寸:使用媒體查詢和斷點設置不同設備下的輪播圖尺寸
  • 控制輪播元素的間距:根據佈局方式選擇合適的間距控制方法
  • 控制每次輪播的位移距離:根據實現方案控制位移步長

以下是輪播佈局在不同斷點下的適配效果:

斷點

效果圖

sm

md

lg

4.6 案例:自定義彈窗的響應式適配

在多設備適配中,彈窗組件需要根據設備尺寸調整大小和佈局。在小屏幕設備上使用緊湊佈局,在大屏幕設備上使用更大的彈窗展示,以避免內容過小不易看清。

以下是自定義彈窗在不同斷點下的適配效果:

斷點

效果圖

sm

md

lg

5. 視頻播放適配

5.1 視頻播放基礎配置

在 HTML 文件中使用 video 標籤:

<video id="myVideo" controls autoplay muted>
  <source src="videos/sample.mp4" type="video/mp4" />
  您的瀏覽器不支持HTML5視頻。
</video>

5.2 視頻全屏適配

Web({
  src: $rawfile("my_web_page/index.html"),
  controller: this.webviewController,
})
  .width("100%")
  .height("100%")
  // 視頻全屏變化回調
  .onFullScreenChange((event) => {
    console.info(`視頻全屏狀態變化: ${event.fullScreen}`);
  });

5.3 視頻播放優化

// 啓用硬件加速
Web({
  src: "https://example.com/video.html",
  controller: this.webviewController,
})
  .width("100%")
  .height("100%")
  // 設置Web組件配置
  .webConfig({
    // 啓用硬件加速
    hardwareAcceleration: true,
    // 啓用媒體自動播放
    mediaPlaybackRequiresUserGesture: false,
  });

6. 深色模式適配

6.1 監聽系統深色模式變化

import { AppStorage } from '@kit.ArkUI';

@Component
export struct DarkModeWebPage {
  private webviewController: webview.WebviewController = new webview.WebviewController();
  // 系統深色模式狀態
  @StorageProp('darkMode') darkMode: boolean = false;

  build() {
    Column() {
      Web({
        src: 'https://developer.huawei.com/consumer/cn/',
        controller: this.webviewController
      })
      .width('100%')
      .height('100%')
      // 監聽深色模式變化
      .onWindowFocus(() => {
        this.updateWebTheme();
      })
    }
    .width('100%')
    .height('100%')
    // 監聽系統主題變化
    .onThemeChange((darkMode) => {
      this.darkMode = darkMode;
      this.updateWebTheme();
    })
  }

  // 更新Web頁面主題
  private updateWebTheme() {
    if (this.darkMode) {
      // 注入JavaScript代碼,切換到深色模式
      this.webviewController.runJavaScript("document.documentElement.setAttribute('data-theme', 'dark');");
    } else {
      // 切換到淺色模式
      this.webviewController.runJavaScript("document.documentElement.setAttribute('data-theme', 'light');");
    }
  }
}

6.2 Web 頁面的深色模式 CSS

/* 淺色模式 */
:root {
  --background-color: #ffffff;
  --text-color: #333333;
  --border-color: #e0e0e0;
}

/* 深色模式 */
[data-theme="dark"] {
  --background-color: #1a1a1a;
  --text-color: #ffffff;
  --border-color: #404040;
}

/* 使用CSS變量 */
body {
  background-color: var(--background-color);
  color: var(--text-color);
  border-color: var(--border-color);
}

7. 性能優化

7.1 頁面加載優化

Web({
  src: "https://developer.huawei.com/consumer/cn/",
  controller: this.webviewController,
})
  .width("100%")
  .height("100%")
  // 預加載DNS
  .dnsPrefetch("https://developer.huawei.com")
  // 啓用緩存
  .webConfig({
    // 啓用頁面緩存
    cacheMode: webview.CacheMode.LOAD_DEFAULT,
    // 啓用DOM存儲
    domStorageAccess: true,
  });

7.2 資源加載控制

// 攔截並控制資源加載
Web({
  src: "https://developer.huawei.com/consumer/cn/",
  controller: this.webviewController,
})
  .width("100%")
  .height("100%")
  // 資源請求攔截
  .onResourceLoadIntercept((event) => {
    const resourceUrl = event.request.getRequestUrl();
    // 過濾廣告資源
    if (resourceUrl.includes("ad.")) {
      return false;
    }
    return true;
  });

7.3 頁面渲染優化

// 啓用平滑滾動
Web({
  src: "https://developer.huawei.com/consumer/cn/",
  controller: this.webviewController,
})
  .width("100%")
  .height("100%")
  .webConfig({
    // 啓用平滑滾動
    smoothScrollEnabled: true,
    // 減少動畫幀延遲
    animationFrameRate: webview.AnimationFrameRate.HIGH,
  });

8. 安全考慮

8.1 安全的資源加載

// 只允許加載HTTPS資源
Web({
  src: "https://developer.huawei.com/consumer/cn/",
  controller: this.webviewController,
})
  .width("100%")
  .height("100%")
  .webConfig({
    // 啓用安全瀏覽
    safeBrowsingEnabled: true,
    // 禁用混合內容
    mixedContentMode: webview.MixedContentMode.BLOCK_ALL,
  });

8.2 JavaScript 注入安全

// 安全地注入JavaScript代碼
private injectSafeScript() {
  // 只注入經過驗證的代碼
  const safeScript = "console.log('安全的JavaScript注入');";
  this.webviewController.runJavaScript(safeScript);
}

8.3 敏感信息保護

// 清除WebView緩存和Cookie
private clearWebData() {
  // 清除緩存
  this.webviewController.clearCache(true);
  // 清除Cookie
  this.webviewController.clearCookies();
  // 清除表單數據
  this.webviewController.clearFormData();
}

9. Web 組件與 Native 通信

9.1 Native 調用 Web 頁面方法

// 調用Web頁面中的JavaScript方法
private callWebMethod() {
  const message = 'Hello from HarmonyOS';
  this.webviewController.runJavaScript(`showMessage("${message}")`);
}

9.2 Web 頁面調用 Native 方法

Web({
  src: $rawfile("my_web_page/index.html"),
  controller: this.webviewController,
})
  .width("100%")
  .height("100%")
  // 註冊JavaScript接口
  .javaScriptProxy({
    object: {
      // 定義Native方法
      showToast: (message: string) => {
        // 顯示Toast
        prompt.showToast({
          message: message,
          duration: prompt.Duration.SHORT,
        });
      },
      // 獲取設備信息
      getDeviceInfo: () => {
        return {
          model: device.deviceModel,
          osVersion: device.osVersion,
        };
      },
    },
    name: "harmonyOS",
    methodList: ["showToast", "getDeviceInfo"],
    controller: this.webviewController,
  });

在 Web 頁面中調用 Native 方法:

// 調用Native的showToast方法
harmonyOS.showToast("Hello from Web Page");

// 調用Native的getDeviceInfo方法
const deviceInfo = harmonyOS.getDeviceInfo();
console.log("設備信息:", deviceInfo);

10. 最佳實踐總結

10.1 開發建議

  1. 合理規劃 Web 資源:根據應用需求選擇本地資源或遠程資源,本地資源加載更快,遠程資源便於更新
  2. 優化頁面加載速度:使用緩存、預加載、資源壓縮等技術提升頁面加載速度
  3. 確保響應式設計:使用 CSS 媒體查詢和彈性佈局,確保在不同設備上都有良好的顯示效果
  4. 適配深色模式:支持系統深色模式,提升用户體驗
  5. 優化視頻播放:啓用硬件加速,支持全屏播放,確保視頻流暢播放

10.2 性能優化

  1. 減少重繪和迴流:優化 CSS 和 JavaScript,減少 DOM 操作
  2. 啓用硬件加速:對視頻、動畫等資源啓用硬件加速
  3. 控制資源加載:攔截不必要的資源請求,減少網絡流量
  4. 合理使用緩存:根據資源類型設置合適的緩存策略

10.3 安全防護

  1. 使用 HTTPS 協議:確保所有網絡請求都使用 HTTPS 協議
  2. 限制 JavaScript 權限:只授予必要的 JavaScript 接口權限
  3. 保護用户隱私:定期清理緩存和 Cookie,保護用户敏感信息
  4. 驗證輸入內容:對用户輸入和 Web 頁面返回的內容進行驗證

11. 常見問題與解決方案

11.1 Web 頁面加載緩慢

問題:Web 頁面加載時間過長,影響用户體驗

解決方案

  • 啓用頁面緩存
  • 預加載常用資源
  • 壓縮 HTML、CSS 和 JavaScript 文件
  • 減少 HTTP 請求數量

11.2 視頻播放卡頓

問題:Web 頁面中的視頻播放不流暢,出現卡頓

解決方案

  • 啓用硬件加速
  • 優化視頻格式和編碼
  • 使用適當的視頻分辨率
  • 確保網絡連接穩定

11.3 深色模式適配問題

問題:Web 頁面在深色模式下顯示異常

解決方案

  • 使用 CSS 變量定義主題顏色
  • 監聽系統深色模式變化
  • 確保所有 UI 元素都支持深色模式

12. 總結

Web 頁面適配是 HarmonyOS 應用開發中的重要內容,通過本文的介紹,您應該已經掌握了 Web 組件的基本使用、響應式佈局適配、視頻播放適配、深色模式適配、性能優化和安全防護等方面的知識。

在實際應用開發中,應根據具體業務需求和場景選擇合適的適配策略,並注意性能優化和安全考慮。希望本文的內容能夠對您有所幫助,祝您在鴻蒙開發之路上越走越遠!

參考文檔

  1. 華為開發者聯盟-ArkWeb
  2. 華為開發者聯盟-Web 與 Native 通信