马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
🎉 博客主页:【剑九_六千里-CSDN博客】【剑九_六千里-掘金社区】
🎨 上一篇文章:【HarmonyOS第四章:样式操纵及渲染页面】
🎠 系列专栏:【HarmonyOS系列】
💖 感谢各人点赞👍收藏⭐批评✍
弁言:
在鸿蒙应用开发中,随着应用复杂度的提升,怎样有用地构造和管理代码成为了一个告急的课题。
本文将探究怎样通过组件化和构建函数的使用来优化代码布局,进步代码的可读性和可维护性。
我们将从组件化的底子开始,渐渐深入到构建函数的高级用法,包罗怎样使用 @Builder 和 @BuilderParam 来进一步增强组件的机动性和复用性。
无论你是刚打仗鸿蒙应用开发的新手还是有肯定履历的开发者,都能从中得到实用的本领和最佳实践。让我们一起探索这些强大的工具吧!
1. 组件化抽取
1.1. 组件拆分及导入导出
刚开始写鸿蒙代码时,我们的代码都是在一个文件中编写,如下:
- @Entry
- @Component
- struct ComponentPage {
- build() {
- Column() {
- Text("header")
- .width("100%")
- .height(200)
- .backgroundColor(Color.Pink)
- Text("content")
- .width("100%")
- .height(200)
- .backgroundColor(Color.Red)
- Text("footer")
- .width("100%")
- .height(200)
- .backgroundColor(Color.Yellow)
- }
- }
- }
复制代码 当页面特殊复杂时,如许写会导致代码量太大,倒霉于后续维护,那么可以接纳下面这种方式:
创建 components/layout 文件夹:
导出每个组件:
- @Component
- export struct Header {
- build() {
- Text("header")
- .width("100%")
- .height(200)
- .backgroundColor(Color.Pink)
- }
- }
复制代码
- @Component
- export struct Content {
- build() {
- Text("content")
- .width("100%")
- .height(200)
- .backgroundColor(Color.Red)
- }
- }
复制代码
- @Component
- export struct Footer {
- build() {
- Text("footer")
- .width("100%")
- .height(200)
- .backgroundColor(Color.Yellow)
- }
- }
复制代码 主页面导入并使用:
- import { Header } from "../components/layout/Header";
- import { Content } from "../components/layout/Content";
- import { Footer } from "../components/layout/Footer";
- @Entry
- @Component
- struct ComponentPage {
- build() {
- Column() {
- Header()
- Content()
- Footer()
- }
- }
- }
复制代码 固然了,在同一个文件中抽取组件也是可行的,如下:
- 在同一文件中通过 @Component 装饰器创建子组件
- 在父组件中引用即可
- @Entry
- @Component
- struct Index {
- build() {
- Column() {
- ListModel()
- }
- .width("100%")
- .height("100%")
- }
- }
- // 同一文件中抽取组件
- @Component
- struct ListModel {
- build() {
- Text(`123`)
- .fontSize(24)
- }
- }
复制代码 2. 构建函数抽取
2.1. @Builder
页面抽取为组件后,组件中有一些相似的内容,又可以抽取为构建函数:
- @Component
- export struct Header {
- // 组件内构建函数:不需要 function 关键字声明
- // 通过 this.ListModel() 调用
- @Builder ListModel() {
- Text(title)
- .fontSize(30)
- .width("100%")
- .height(100)
- .backgroundColor(Color.Pink)
- }
- build() {
- Column() {
- this.ListModel()
- }
- }
- }
- // 全局构建函数:需要 function 关键字声明
- // 直接 ListModel() 调用
- // @Builder function ListModel() {
- // Text("你好")
- // .fontSize(30)
- // .width("100%")
- // .height(100)
- // .backgroundColor(Color.Pink)
- // }
复制代码 2.2. @Builder传参转达
1)按值转达
- @Component
- export struct Header {
- // 组件内构建函数:不需要 function 关键字声明
- // 通过 this.ListModel() 调用
- @Builder ListModel(title: string) {
- Text(title)
- .fontSize(30)
- .width("100%")
- .height(100)
- .backgroundColor(Color.Pink)
- }
- build() {
- Column() {
- this.ListModel("你好")
- }
- }
- }
- // 全局构建函数:需要 function 关键字声明
- // 直接 ListModel() 调用
- // @Builder function ListModel(title: string) {
- // Text(title)
- // .fontSize(30)
- // .width("100%")
- // .height(100)
- // .backgroundColor(Color.Pink)
- // }
复制代码 2)按引用转达
- 名称总数通过参数转达
- 可转达多个参数
- 点击按钮增长总数
- interface IOptions {
- name: string;
- count: number;
- }
- @Component
- export struct Header {
- @State count: number = 1;
- // 组件内构建函数:不需要 function 关键字声明
- // 通过 this.ListModel() 调用
- @Builder ListModel(options: IOptions) {
- Text(`${options.name}-------------------${options.count}`)
- .width("100%")
- .height(20)
- .backgroundColor(Color.Pink)
- }
- build() {
- Column() {
- this.ListModel({name: "Header", count: this.count})
- this.ListModel({name: "Header", count: this.count * 2})
- this.ListModel({name: "Header", count: this.count * 4})
- Button("增加count").onClick(() => {
- this.count++;
- })
- }
- }
- }
- // 全局构建函数:需要 function 关键字声明
- // 直接 ListModel() 调用
- // @Builder function ListModel(options: IOptions) {
- // Text(`${options.name}-------------------${options.count}`)
- // .width("100%")
- // .height(20)
- // .backgroundColor(Color.Pink)
- // }
复制代码 留意:
- 在使用 @Builder 复用逻辑时,可以支持转达参数,从而实现更机动的UI渲染。
- 参数可以是状态数据,但发起使用对象的方式举行转达(直接转达,无法实现视图更新)。
- 可以使用 Component 来抽象组件,而 @Builder 则可以实现轻量级的UI复用。
- 按引用转达,参数界说范例时,不能使用字面量情势,必要使用 interface 大概 type 界说。
3. 构建函数插槽 @BuilderParam
@BuilderParam 是一个装饰器,用于声明恣意 UI 形貌的一个元素,类似于 slot 占位符。
当开发者创建了自界说组件,并想对该组件添加特定功能时,比方在自界说组件中添加一个点击跳转操纵。
若直接在组件内嵌入事故方法,将会导致全部引入该自界说组件的地方均增长了该功能。
为办理此题目,ArkUI 引入了 @BuilderParam 装饰器,@BuilderParam 用来装饰指向 @Builder 方法的变量,开发者可在初始化自界说组件时对此属性举行赋值,为自界说组件增长特定的功能。
3.1. 尾随闭包初始化组件(默认插槽)
- 组件后加 {} 誊写,称为尾随闭包
- 组件多次使用时,如未转达插槽,需通过 @Builder 声明默认内容
- // @BuilderParam
- @Entry
- @Component
- struct Index {
- build() {
- Column() {
- ListModel() {
- // 传递默认插槽
- Text("默认插槽")
- .fontSize(24)
- }
- // 此处未使用插槽
- ListModel()
- }
- .width("100%")
- .height("100%")
- }
- }
- @Component
- struct ListModel {
- // 使用父组件的尾随闭包{}(@Builder装饰的方法)初始化子组件@BuilderParam
- @BuilderParam ListModelFn: () => void = this.ListModelDefaultFn;
- // 如果默认插槽未传递,则默认一个内容
- @Builder ListModelDefaultFn () {
- Text("这是默认内容")
- }
- build() {
- Column() {
- Text("尾随闭包")
- .fontSize(24)
- // 接收默认插槽
- this.ListModelFn()
- }
- }
- }
复制代码 3.2. 参数初始化组件(具名插槽)
- @BuilderParam 装饰的方法可以是有参数和无参数的两种情势,需与指向的 @Builder 方法范例匹配。
- @BuilderParam 装饰的方法范例必要和 @Builder 方法范例同等。
- @BuilderParam 装饰的方法必须要有默认值,要不会报错,默认值是一个函数,通过 @Builder 装饰
- @Entry
- @Component
- struct Index {
- @Builder HeaderContent() {
- Text("上部分内容")
- .fontColor(Color.White)
- .height(40)
- .backgroundColor(Color.Blue)
- .width("100%")
- .textAlign(TextAlign.Center)
- }
- @Builder FooterContent() {
- Text("下部分内容")
- .fontColor(Color.White)
- .height(40)
- .backgroundColor(Color.Blue)
- .width("100%")
- .textAlign(TextAlign.Center)
- }
- build() {
- Column({space:10}) {
- ListModel({ title:"中间内容",
- HeaderCon: this.HeaderContent, // 可以传递多个插槽,只传递,不调用
- FooterCon: () => { this.FooterContent() } // 也可以才有箭头函数的形式传递
- })
- }
- .width('100%')
- .height('100%')
- }
- }
- @Component
- struct ListModel {
- title:string = "";
- @BuilderParam HeaderCon:() => void = this.Default;
- @BuilderParam FooterCon:() => void = this.Default;
- // 必须要有默认值,要不会报错
- @Builder Default () {
- Text("")
- }
- build() {
- Column(){
- // 组件中调用
- this.HeaderCon()
- Text(this.title)
- .width("100%")
- .height(40)
- .textAlign(TextAlign.Center)
- .fontColor(Color.White)
- .backgroundColor(Color.Red)
- // 组件中调用
- this.FooterCon()
- }
- .width("100%")
- }
- }
复制代码 |