鸿蒙学习实战之路-Web 页面适配最佳实践 - 实践

鸿蒙学习实战之路-Web 页面适配最佳实践

Web 页面适配是 HarmonyOS 应用开发中常见的需求,本文将介绍如何在鸿蒙应用中实现 Web 页面的最佳适配方案,包括基础使用、响应式布局、视频播放适配、深色模式适配等内容。

关于本文

自己学习并使用 HarmonyOS Web 组件的记录,旨在帮助小伙伴们少走弯路

华为开发者联盟-Web 组件文档永远是你的好伙伴,请收藏!

  • 本文并不能代替官方文档,所有的内容也都是基于官方文档+自己尝试的记录。
  • 基本所有章节基本都会附上对应的文档链接,强烈建议你点看看看
  • 所有结合代码操作的部分,建议自己动手尝试一下

代码测试环境

环境/工具版本/说明
DevEco Studio5.0.3.400
HarmonyOS SDKAPI Version 12
Node.js18.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 页面适配效果:

断点效果图
smsm断点效果
mdmd断点效果
lglg断点效果

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>

    上述示例代码的运行效果如下:

    宫格布局示例代码效果图

  4. 自适应布局:为不同设备尺寸创建不同的布局方案

4.5 案例:轮播布局的响应式适配

轮播布局(轮播图)是 Web 开发中常用的组件之一,需要特别注意其响应式适配。轮播布局的适配关键点包括:

  • 控制轮播元素的尺寸:使用媒体查询和断点设置不同设备下的轮播图尺寸
  • 控制轮播元素的间距:根据布局方式选择合适的间距控制方法
  • 控制每次轮播的位移距离:根据实现方案控制位移步长

以下是轮播布局在不同断点下的适配效果:

断点效果图
smsm断点轮播效果
mdmd断点轮播效果
lglg断点轮播效果

4.6 案例:自定义弹窗的响应式适配

在多设备适配中,弹窗组件需要根据设备尺寸调整大小和布局。在小屏幕设备上使用紧凑布局,在大屏幕设备上使用更大的弹窗展示,以避免内容过小不易看清。

以下是自定义弹窗在不同断点下的适配效果:

断点效果图
smsm断点弹窗效果
mdmd断点弹窗效果
lglg断点弹窗效果

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 通信
posted @ 2026-01-05 22:29  gccbuaa  阅读(48)  评论(0)    收藏  举报