鸿蒙开发自定义构建函数&自定义组件【华为根技术】
        【摘要】 @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)