ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

HarmonyOS 多设备短视频开发 : 11 — ArkUI 声明式开发范式

2026/8/31 11:29:56 拓冰建站 浏览量
HarmonyOS 多设备短视频开发 : 11 — ArkUI 声明式开发范式 11 — ArkUI 声明式开发范式一、引言HarmonyOS ArkUI 采用声明式开发范式开发者只需要描述界面长什么样、数据如何驱动界面而无需关心如何一步步把控件添加到屏幕上。相比传统的命令式开发如安卓 View 体系的 findViewById setXxx声明式范式把状态变化 → 界面刷新的联动交由框架自动完成。本文以多设备短视频项目multi-short-video中的真实代码为线索剖析 ArkUI 声明式开发的核心要素state - view模型、struct 组件、build 函数以及链式属性调用。二、从命令式到声明式state - view 模型命令式开发中界面与数据之间是手工同步的关系数据变化后需要开发者显式调用更新方法漏掉任何一处都会出现界面与数据不一致的 Bug。声明式开发则把这条链路收敛为单向数据流graph LR A[状态 state] -- B[声明式 UI 描述 view] B -- C[框架渲染] C -- D[事件回调] D --|修改| A当state变化时ArkUI 框架自动重渲染依赖该状态的组件。以features/multishortvideocomment/src/main/ets/view/Comment.ets为例评论数据与界面是典型的绑定关系ComponentV2 export struct Comment { Local commentData: CommentDataModel[] []; Local commentInput: string ; controller: TextInputController new TextInputController(); aboutToAppear(): void { this.commentData new CommentViewModel().getCommentList(); } // build() 中 List 直接遍历 this.commentData 渲染 }开发者只声明commentData与 UI 的对应关系评论数据在aboutToAppear中赋值后列表自动刷新用户在输入框键入内容时commentInput与TextInput通过text: this.commentInput双向联动。整个过程中没有一行手动刷新代码。三、struct 组件与 build 函数ArkUI 中每个自定义组件都是一个struct通过ComponentV2装饰器声明为组件build()描述组件树。公共模块common/multishortvideobase/src/main/ets/components/MSVTextIcon.ets是一个精简且极具代表性的声明式组件ComponentV2 export struct MSVTextIcon { Require Param src: PixelMap | ResourceStr | DrawableDescriptor; Param iconSize: Length 32; Param iconOnly: boolean true; Param content: string | Resource ; Param fontSize: string | number | Resource $r(sys.float.Body_M); Param fontColor: ResourceColor $r(sys.color.font_on_primary); Param fontWeight: number | FontWeight | ResourceStr $r(sys.float.font_weight_regular); Param gap: Length 2; build() { Column({ space: this.gap }) { Image(this.src) .width(this.iconSize) .aspectRatio(1) .objectFit(ImageFit.Contain) if (!this.iconOnly) { Text(this.content) .fontSize(this.fontSize) .fontColor(this.fontColor) .fontWeight(this.fontWeight) } } } }Param声明对外入参父组件传入Require标记必填参数build()内用Column、Image、Text描述组件结构并通过if (!this.iconOnly)条件渲染实现纯图标 / 图标文字两种形态的切换。调用方只需一行声明式描述即可复用MSVTextIcon({ src: $r(app.media.ic_heart_fill), iconOnly: false, content: 1557, iconSize: 32 })四、组件属性与事件链式调用声明式范式的另一大特征是链式调用每个组件方法都返回组件自身属性与事件可以无限串联。Comment.ets中评论内容的文本样式是典型的链式调用Text(item.item.content) .fontSize(deviceInfo.deviceType tv ? 24 : $r(sys.float.Body_L)) .fontColor(new WidthBreakpointTypeResourceColor($r(sys.color.font_primary), $r(sys.color.font_primary), $r(sys.color.font_on_primary), $r(sys.color.font_on_primary)).getValue(this.windowInfo.widthBp)) .fontWeight($r(sys.float.font_weight_regular)) .padding({ top: 9.5, bottom: 9.5 })这里串联了字号、颜色、字重、内边距四个属性其中颜色通过WidthBreakpointType工具类按窗口断点取值实现浅色/深色与多设备的自适应。事件同样以链式方式绑定如视频页AdaptiveVideo.ets中点击头像跳转个人作品页MSVTextIcon({ src: $r(app.media.ic_user_avatar), iconSize: 44 }) .gesture( TapGesture() .onAction(() { if (this.windowInfo.widthBp WidthBreakpoint.WIDTH_SM) { this.showSideIndividual true; this.pathStack.pushPathByName(IndividualByRouter, null); } else { this.pathStack.pushPathByName(IndividualByRouter, null); } }))属性链描述外观事件链描述行为二者合起来就是组件的完整 UI 契约可读性远高于命令式代码。五、通用属性与常量约定width、height、padding、margin 等通用属性作用于所有组件。为避免魔法字符串项目在common/multishortvideobase/src/main/ets/constants/CommonConstants.ets中统一定义了百分比常量常量值用途FULL_PERCENT100%组件撑满父容器SEVENTY_FIVE_PERCENT75%半模态评论弹窗高度HALF_PERCENT50%圆形按钮、头像MIDDLE_DOT_SYMBOL·信息分隔符Comment.ets中评论列表与输入框均通过CommonConstants.FULL_PERCENT设置全宽视频页评论按钮的圆角使用HALF_PERCENT达成圆形效果。统一常量既保证了多文件风格一致也方便全局调整。六、总结与最佳实践坚持单向数据流界面只依赖状态业务逻辑只修改状态由框架驱动刷新避免手工操作 DOM。组件化优先将高频 UI如MSVTextIcon抽成 struct 组件用Param定义入参契约。善用链式调用属性与事件按外观→行为顺序组织保持一个组件描述集中、可读。常量化管理尺寸、颜色、符号统一收敛到CommonConstants与资源文件杜绝魔法值。状态粒度要细Local只放真正参与渲染的状态普通字段如controller不需要装饰器减少不必要的重渲染。