
HarmonyOS自定义构建函数 原创
1. 构建函数-@Builder
如果不想使用 @Component 直接抽象组件,ArkUI还提供了一种更轻量的UI元素复用机制 @Builder,可以将重复使用的UI元素抽象成一个方法,在 build 方法里调用。称之为自定义构建函数。
用法- 可以使用 @Builder 修饰符进行修饰。
例如上面图片设置页面的每个操作项,可以单独的抽离出来,进行复用。
案例代码如下:
实现效果,如图所示。
假设有N个这样的单个元素,但是重复的去写会浪费大量的代码,丧失代码的可读性,此时我们就可以使用builder构建函数。
1.1 全局定义- @Builder functionname () {}
使用@Builder抽取组件代码,如下所示
在组件中使用,完整代码如下:
实现效果,如图所示。
全局自定义函数的问题
· 全局的自定义构建函数可以被整个应用获取,不允许使用this和bind方法。
· 如果不涉及组件状态变化,建议使用全局的自定义构建方法。
· 补一句-如果数据是响应式的-此时该函数不会自动渲染-哪怕是全局自定义函数,不可被其他文件引用。
将数据声明为State响应式数据
传递数据,绑定为对应字段,代码如下:
修改响应式数据,完整代码如下:
实现效果,如图所示。
我们发现,点击修改数据-语言切换按钮是没有任何反应的,说明此时即使用了State,但是此时的全局builder依然不更新。
那怎么办?我们试试在组件内部定义。
1.2 组件内定义- 语法 @Builder name () {}
把@Builder标注的代码部分,放置到组件内部,完整代码如下:
实现效果,如图所示:
调用多了this,其他和全局属性一样,没有任何变化,此时我们发现修改数据依然没有任何变化,这是为什么呢?
注意:我们刚刚传过去的是什么类型,string是一个基础数据类型,它是按值传递的,不具备响应式更新的特点。
总结
全局Builder函数和组件Builder构建函数可以实现一种轻量级的UI复用。
区别: 全局自定义构建函数不允许使用this,bind,它适合一种纯渲染的UI结构。
组件内自定义Builder可以实现this调用。
2. 构建函数-传参传递
自定义构建函数的参数传递有按值传递和按引用传递两种,均需遵守以下规则:
参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。
在自定义构建函数内部,不允许改变参数值。如果需要改变参数值,且同步回调用点,建议使用@Link。
@Builder内UI语法遵循UI语法规则。
我们发现上一个案例,使用了string这种基础数据类型,即使它属于用State修饰的变量,也不会引起UI的变化。
按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder方法内的UI刷新。ArkUI提供$$作为按引用传递参数的范式。
格式如下:
也就是我们需要在builder中传入一个对象,该对象使用$$(可使用其他字符)的符号来修饰,此时数据具备响应式了。
定义IOptions接口,在@Builder中传入IOptions接口。
传递参数值,代码如下:
修改后的完整代码如下;
实现效果,如图所示。
这里,点击“修改数据-语言切换”按钮,语言切换的数据发生改变。
同样的,全局 Builder 也支持这种用法,完整代码如下。
使用 @Builder 复用逻辑的时候,支持传参可以更灵活的渲染UI。
参数可以使用状态数据,不过建议通过对象的方式传入 @Builder。
3. 构建函数-@BuilderParam 传递UI
Component可以抽提组件。
Builder可以实现轻量级的UI复用。
完善了吗?其实还不算,比如下面这个例子,如图所示。
大家发现没有,项目中会有很多地方用到这种类似卡片 Card 的地方,里面的内容各有不同,怎么办?
在 Vue 里面有个叫做 slot 插槽的东西,就是可以传入自定义的结构,整体复用父组件的外观。
ArkTS提供了一个叫做 BuilderParam 的修饰符,可以在组件中定义这样一个函数属性,在使用组件时直接传入。
BuilderParam只能应用在 Component 组件中,不能使用 Entry 修饰的组件中使用。
语法:
声明一个HmCard组件
父组件调用传入
完整代码如下:
运行效果,如图所示。
需要注意的是,传入的函数必须是使用 Builder 修饰符修饰的。
BuilderParams类似于 Vue 中的插槽。
(1)子组件中定义一个用 BuilderParam 修饰的函数。
(2)父组件需要给子组件传入一个用 Builder 修饰的函数来赋值给子组件。
(3)子组件要在想要显示插槽的地方来调用传入的方法。
插槽默认值
当我们的调用组件的时候,如果没有给插槽传递参数值,则这个时候我们可以给 BuilderParam 函数默认值,代码如下。
实现效果,如图所示:
尾随闭包
当我们的组件只有一个BuilderParam 的时候,此时可以使用尾随闭包的语法也就是像我们原来使用Column或者Row组件时一样,直接在大括号中传入,代码格式如下:
如果有多个呢,不好意思,必须在组件的函数中老老实实的传入多个builder自定义函数。
完整代码如下:
实现效果,如图所示。
4. 案例
封装 HmCard 和 HmCardItem 组件,使用 BuilderParam 属性完成如下效果图。
完整代码如下:
