在移动应用开发领域,鸿蒙系统(HarmonyOS)作为华为推出的全场景分布式操作系统,为开发者提供了全新的开发范式。本文将深入探讨鸿蒙应用开发中的两个核心概念:自定义组件与页面路由。通过系统性的讲解和丰富的示例,帮助开发者掌握构建复杂鸿蒙应用的关键技术。
自定义组件是鸿蒙应用开发中构建用户界面的基本单元,它封装了特定的UI元素和交互逻辑,具有以下特点:
独立性:每个组件拥有自己的状态和行为
可复用性:可以在应用的不同位置重复使用
组合性:简单组件可以组合成复杂组件
可配置性:通过参数接受外部配置
在鸿蒙开发中,我们使用@Component
装饰器来定义自定义组件。下面是一个完整的组件示例:
@Component
export struct ArticleCard {
// 组件参数
private title: string = '默认标题'
private author: string = '匿名'
@State private isLiked: boolean = false
// 构建方法
build() {
Column({ space: 10 }) {
Text(this.title)
.fontSize(18)
.fontWeight(FontWeight.Bold)
Text(`作者: ${this.author}`)
.fontSize(14)
.fontColor('#999')
Row() {
Image(this.isLiked ? $r('app.media.liked') : $r('app.media.unliked'))
.width(20)
.height(20)
.onClick(() => {
this.isLiked = !this.isLiked
})
Text(this.isLiked ? '已赞' : '点赞')
.margin({ left: 5 })
}
}
.padding(15)
.borderRadius(8)
.backgroundColor('#FFF')
.shadow({ radius: 4, color: '#00000020', offsetX: 1, offsetY: 1 })
}
}
鸿蒙提供了多种装饰器来管理组件状态:
@State:组件内部状态,变化会触发UI更新
@Prop:从父组件传递的单向绑定数据
@Link:与父组件双向绑定的数据
@Provide/@Consume:跨组件层级的数据共享
@Component
export struct ParentComponent {
@State private counter: number = 0
build() {
Column() {
ChildComponent({
propCounter: this.counter,
linkCounter: $counter
})
Button('增加计数')
.onClick(() => {
this.counter++
})
}
}
}
@Component
struct ChildComponent {
@Prop propCounter: number
@Link linkCounter: number
build() {
Row() {
Text(`Prop: ${this.propCounter}`)
Text(`Link: ${this.linkCounter}`)
Button('修改Link')
.onClick(() => {
this.linkCounter++
})
}
}
}
理解组件生命周期对于正确管理资源和状态至关重要:
@Component
export struct LifecycleDemo {
// 初始化时调用
aboutToAppear() {
console.log('组件即将显示')
}
// 构建UI
build() {
// ...
}
// 组件销毁时调用
aboutToDisappear() {
console.log('组件即将消失')
}
}
鸿蒙的路由系统提供了页面导航和跳转的能力,主要特点包括:
基于URL的路由配置
支持参数传递
多种路由模式选择
完整的生命周期管理
返回结果处理
在resources/base/profile/main_pages.json
中配置应用路由:
{
"src": [
"pages/Home",
"pages/ProductList",
"pages/ProductDetail",
"pages/UserProfile",
"pages/Settings"
]
}
基本跳转
import router from '@ohos.router'
// 简单跳转
router.push({
url: 'pages/ProductList'
})
// 带参数跳转
router.push({
url: 'pages/ProductDetail',
params: {
productId: '12345',
from: 'home'
}
})
替换当前页面
router.replace({
url: 'pages/Login'
})
返回上一页
// 简单返回
router.back()
// 返回并传递结果
router.back({
url: 'pages/Home',
params: {
result: 'success'
}
})
在目标页面接收参数:
@Entry
@Component
struct ProductDetail {
private productId: string = ''
private fromPage: string = ''
onPageShow() {
const params = router.getParams()
this.productId = params['productId'] as string
this.fromPage = params['from'] as string
// 根据productId加载数据
this.loadProductDetail()
}
build() {
// ...
}
}
鸿蒙提供两种路由模式:
Standard模式(默认):
每次跳转创建新实例
适用于大多数场景
内存消耗相对较大
Single模式:
复用已有实例
适用于频繁访问的页面
需要手动刷新数据
router.push({
url: 'pages/Settings',
mode: router.RouterMode.Single
})
组件拆分原则:
按功能划分组件
保持组件单一职责
控制组件粒度(300-500行为宜)
性能优化技巧:
使用@Reusable
装饰器实现组件复用
避免在build方法中进行复杂计算
合理使用aboutToAppear
和aboutToDisappear
生命周期
路由拦截实现示例:
// 全局路由拦截
router.addInterceptor((from, to, next) => {
if (to.url === 'pages/UserProfile' && !isLogin) {
next({ url: 'pages/Login' })
} else {
next()
}
})
深度链接处理:
// 处理应用外部的URL请求
router.handleUrl((url) => {
if (url.startsWith('harmony://product/')) {
const productId = url.split('/').pop()
router.push({
url: 'pages/ProductDetail',
params: { productId }
})
}
})
// 全局状态管理
class AppState {
@Track cartItems: Array = []
addToCart(itemId: string) {
this.cartItems.push(itemId)
}
}
// 在路由跳转时传递状态
router.push({
url: 'pages/Checkout',
params: {
__state: JSON.stringify(appState)
}
})
问题1:组件状态不更新
检查是否使用了正确的装饰器(@State, @Prop等)
确保直接修改状态值而不是重新赋值
问题2:样式不生效
检查样式优先级
确认父组件的约束条件
问题1:参数传递失败
检查参数是否可序列化
确认目标页面是否正确接收
问题2:页面返回刷新
使用onPageShow生命周期处理数据刷新
考虑使用Single模式+手动刷新
鸿蒙系统的自定义组件和页面路由机制为开发者提供了强大的工具集,通过本文的系统讲解,相信您已经掌握了:
如何设计和实现高质量的自定义组件
灵活运用各种路由方式进行页面导航
高级状态管理与路由结合的技巧
常见问题的诊断和解决方法
随着鸿蒙生态的不断发展,这些核心技术将帮助您构建出体验优秀、性能卓越的全场景应用。建议读者结合实际项目多加练习,深入理解这些概念的内在联系,从而提升鸿蒙应用开发的整体水平。