
网罗开发 (小红书、快手、视频号同名)
大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验 。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索"展菲",即可纵览我在各大平台的知识足迹。
📣 公众号"Swift社区",每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友"fzhanfei",与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!
文章目录
-
- 引言
- [UI 复用不只是组件](#UI 复用不只是组件)
- 第一层:结构复用(Component)
- [第二层:样式复用(Style 抽离)](#第二层:样式复用(Style 抽离))
- 第三层:逻辑复用(行为抽离)
- 第四层:状态复用(Store)
- 一个常见误区:组件越多复用越好?
- [ArkUI 中更推荐的复用方式](#ArkUI 中更推荐的复用方式)
- [UI 复用的本质](#UI 复用的本质)
- 总结
引言
很多开发者在做 ArkUI 项目时,都会有一个"错觉":
组件写出来就算复用了。
比如把一段 UI 抽成组件:
ts
@Component
struct UserCard {
@Prop name: string
build() {
Text(this.name)
}
}
然后在多个地方使用:
ts
UserCard({ name: "Tom" })
UserCard({ name: "Jerry" })
看起来已经实现了"复用"。但当项目变大之后,你会发现一些问题开始出现:
组件越来越多
样式重复
逻辑分散
修改成本变高
甚至会出现一种情况:
看起来在复用,其实在复制。
这说明一个问题:
你用的是"组件复用",但没有理解 ArkUI 的"UI 复用机制"。
UI 复用不只是组件
很多人理解的复用是:
写组件 → 多处使用
但在 ArkUI 中,UI 复用其实有多个层级:
结构复用
样式复用
逻辑复用
状态复用
如果只做了组件抽离,其实只解决了:
结构复用
而真正的复杂项目,需要解决的是:
多层级的复用问题。
第一层:结构复用(Component)
这是最基础的一层。
通过 @Component 抽离 UI 结构:
ts
@Component
struct ButtonPrimary {
@Prop text: string
build() {
Button(this.text)
.backgroundColor(Color.Blue)
.fontColor(Color.White)
}
}
使用:
ts
ButtonPrimary({ text: "提交" })
这解决的是:
UI结构统一
代码减少重复
但问题是:
结构复用 ≠ 可维护复用
因为一旦样式变化,你可能需要改很多组件。
第二层:样式复用(Style 抽离)
很多 ArkUI 项目会出现这样的代码:
ts
Text("标题")
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin(10)
这种写法在多个地方重复。正确做法是:
抽离样式。
例如:
ts
const TitleStyle = {
fontSize: 18,
fontWeight: FontWeight.Bold
}
使用:
ts
Text("标题")
.fontSize(TitleStyle.fontSize)
.fontWeight(TitleStyle.fontWeight)
或者进一步封装:
ts
@Component
struct TitleText {
@Prop text: string
build() {
Text(this.text)
.fontSize(18)
.fontWeight(FontWeight.Bold)
}
}
这样可以做到:
统一视觉风格
降低修改成本
第三层:逻辑复用(行为抽离)
很多 UI 组件不仅有结构,还有逻辑。例如:
ts
Button("提交")
.onClick(() => {
if (!this.isValid()) {
return
}
this.submit()
})
如果多个地方都有类似逻辑,就会出现:
逻辑重复
难以维护
容易出 bug
正确做法是:
抽离逻辑层。
例如:
ts
class FormService {
static submit(data) {
// 校验 + 请求
}
}
组件中只调用:
ts
Button("提交")
.onClick(() => {
FormService.submit(this.formData)
})
这样实现:
逻辑复用
UI 解耦
第四层:状态复用(Store)
很多复杂 UI 的核心不是结构,而是:
状态。
例如:
用户信息
购物车数据
订单状态
如果这些状态写在组件里:
ts
@State userInfo: User
那复用几乎是不可能的,因为:
每个组件都有自己的状态
数据不同步
逻辑重复
正确做法是:
状态集中管理。
例如:
ts
class UserStore {
user: User = {}
setUser(user: User) {
this.user = user
}
}
组件中使用:
@Consume userStore
这样多个组件共享同一状态,这才是真正的:
状态复用。
一个常见误区:组件越多复用越好?
很多项目会陷入一个误区:
组件越细 → 复用越好
于是出现:
Text组件
Button组件
Wrapper组件
Container组件
结果反而变成:
组件爆炸
结构复杂
阅读困难
真正合理的方式是:
按"业务语义"拆组件。
例如:
UserCard
OrderItem
ProductCard
而不是:
BlueText
PaddingBox
RoundedView
因为后者只是"样式复用",不是"业务复用"。
ArkUI 中更推荐的复用方式
在中大型项目中,一个比较合理的复用结构通常是:
基础组件层(Base)
↓
业务组件层(Business)
↓
页面组合层(Page)
例如:
BaseButton
BaseCard
BaseText
↓
UserCard
OrderCard
ProductCard
↓
UserPage
OrderPage
这样可以做到:
基础能力复用
业务语义清晰
页面结构简单
UI 复用的本质
很多开发者把复用理解为:
少写代码。
但实际上,UI 复用的本质是:
降低复杂度。
如果你的复用带来了:
更多层级
更难理解
更难修改
那它其实是失败的,好的复用应该是:
结构清晰
职责明确
修改成本低
总结
ArkUI 的 UI 复用,并不仅仅是"写组件"。而是一个多层级的体系:
结构复用(Component)
样式复用(Style)
逻辑复用(Service)
状态复用(Store)
如果只做组件抽离,很容易陷入:
看起来在复用,其实在复制。
真正高质量的 ArkUI 项目,通常具备这些特点:
组件有语义
状态集中管理
逻辑独立
结构清晰
当你把这些做好之后,你会发现:
UI 不只是可以复用,而且可以"组合"。
这也是 ArkUI 声明式 UI 最大的价值之一。