鸿蒙开发自定义构建函数&自定义组件【华为根技术】
【摘要】 @Builder装饰器:自定义构建函数https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5ArkUI提供了一种轻量的UI元素复用机制@Builder,其内部UI结构固定,仅与使用方进行数据传递,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用。为了简化语言,我们将...
@Builder装饰器:自定义构建函数
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5
ArkUI提供了一种轻量的UI元素复用机制@Builder,其内部UI结构固定,仅与使用方进行数据传递,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用。
为了简化语言,我们将@Builder装饰的函数也称为“自定义构建函数”。
-
应用场景
@Builder私有自定义构建函数
-
私有的在组件内部定义,前面不加function
-
私有的自定义构建函数,调用时要加this
-
私有的可以访问组件状态
@Component
struct Test{
@State a: string = ''
// 自定义构建函数
@Builder
//title为自定义函数名
//text为函数调用时传来的参数,参数可以有,也可以没有
title(text: string) {
Row() {
...
}
.width('100%')
.height(56)
}
build(){
Column(){
Text('aaa')
//调用自定义构建函数
this.title()
}
}
}
@Builder全局自定义构建函数
-
全局的在组件外部定义,前面必须加function
-
全局的自定义构建函数,调用时不加this
-
全局的不能访问组件状态
@Builder
function title(txt: string, content: string) {
Row() {
Text(txt)
Text('-------')
Text(`这个${content}也不一样`)
Blank()
Text("查看更多-----")
Text(this.activeIndex.toString()) // 报错,不能访问组件的状态
}
.border({ width: 1, color: '#f00' })
.width('100%')
}
@Entry
@Component
struct Test {
@State activeIndex: number = 8
build() {
Column() {
//调用全局的Builder
title('1', '冰天')
}
}
}
创建自定义组件
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-create-custom-components-V13
-
认识组件
-
在ArkUI中,UI显示的内容均为组件,
-
由框架直接提供的称为系统组件
-
由开发者定义的称为自定义组件
在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑与UI分离,后续版本演进等因素。因此,将UI和部分业务逻辑封装成自定义组件是不可或缺的能力。
-
自定义组件特点:
-
可组合:允许开发者组合使用系统组件、及其属性和方法。
-
可重用:自定义组件可以被其他组件重用,并作为不同的实例在不同的父组件或容器中使用。
-
数据驱动UI更新:通过状态变量的改变,来驱动UI的刷新。
-
创建自定义组件
子组件.ets
@Component
export struct ChildComponent {
// @Prop message: string = '' // 单向数据绑定
// @Link message: string = '' // 双向数据绑定
build() {
Text('改变message')
.onClick(()=>{
this.message = 'how are you'
})
}
}
父组件.ets
总结
声明: 下面提到的State是指父子组件传递的参数
-
@State接收参数如果用@State接收父组件的传参,当父组件的State改变时,子组件不会更新(同步)
-
@Prop 接收参数@Prop单向数据绑定@Prop装饰器用来接收父组件的传参,可以不定义初始值用@Prop接收的参数,在父组件的State改变时,子组件也会更新用@Prop接收的参数,在子组件修改后,子组件更新,但父组件不更新
-
@Link接收参数@Link 实现双向数据绑定父组件State修改,子组件会更新子组件State修改,父组件也会更新@Link不能初始值
传递多个参数,传复杂数据
父组件
import { TopBar } from "../common/TopBar"
//
/**
* TS的数据类型分两大类
* 1. 基本数据类型 string number boolean ...
* name = 'bbbb'
* 2. 引用数据类型 数组[] 对象{}
* arr = ['aaa','bbb']
* obj = {
* username: 'aaaa',
* desc: 'bbbb'
* }
*/
export interface StudentModel {
name: string,
age: number,
gender: string
}
@Entry
@Component
export struct Rank {
@State message: string = '热销榜'
@State student: StudentModel = {
name: '张三',
age: 16,
gender: '其他'
}
build() {
Column() {
Text("当前是榜单页")
TopBar({
title: this.message,
color: '红色',
stu: this.student
})
}
.width('100%')
.height('100%')
}
}
子组件
import { StudentModel } from "../pages/Rank"
@Component
export struct TopBar {
@Prop title: string
@Prop color: string
@Prop stu: StudentModel
build() {
Row() {
Text("返回箭头").margin(10)
Text(this.title)
Blank()
Text(this.color)
Text(this.stu.name)
}
.width("100%")
.height("40")
.border({ width: 1, color: '#f00' })
.backgroundColor(Color.Orange)
}
}
@Provide和@Consume实现后代组件的双向绑定
-
@Provide装饰器可以向后代组件传递参数
-
@Consume装饰器接收祖先组件传递的参数
-
二者实现的是数据的双向绑定,也就是祖先和后代任意一方修改数据,都能同步更新
案例代码
祖先组件
import { Child } from '../common/Child'
@Entry
@Component
struct Index {
// @Provide装饰器可以向后代组件传递参数
@Provide color: string = '祖先组件的红色'
@Provide("student") a: string = '张三'
build() {
Column(){
// Button("改变数据")
// .onClick(()=>{
// this.color = '新的绿色'
// })
Text(this.color)
Text("首页-父组件")
Divider().color(Color.Red)
Child()
}
}
}
子组件
import { GrandSon } from "./GrandSon"
@Component
export struct Child {
build() {
Column() {
Text('这是子组件')
GrandSon()
}
.width("100%")
.height(350)
.border({ width: 1, color: '#f00' })
}
}
后代组件
@Component
export struct GrandSon {
// @Consume装饰器接收祖先组件传递的参数
@Consume color: string
// 接收student, 同时可以给变量一个别名
// 如果接收的数据和当前组件中的状态名冲突,就可以创建别名
@Consume("student") name: string
build() {
Column() {
Button("改变数据")
.onClick(()=>{
this.color = '新的绿色'
})
Text("这是孙组件")
Text(this.color)
Text(this.name)
}
.width('100%')
.border({ width: 1, color: '#0f0' })
}
}
把方法做为参数进入传递
@Entry
@Component
struct Del {
@State message: string = '我是父组件的信息'
show(){
// AlertDialog.show({
// message: this.message
// })
console.log('aaaa')
}
build() {
Row(){
Text("父组件")
Child({
show: this.show
})
}
.width(300)
.height(160)
}
}
@Component
struct Child {
show: () => void = () => {
};
build() {
Button("单击,会调用父组件的方法").onClick(()=>{
this.show()
})
}
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)