鸿蒙 OS-04 装饰器@Component @Build @Styles @Extend自定义组件

302 阅读3分钟

图片来源:黑马程序员 bz

总结: 自定义组件如果单独的 ets file.需要加上 export. import

@Component
export struct Header{...}

import {Header} from '../common/components/CommonComponents'

image.png

image.png

通用组件的编写.eg:带有参数的 Header

IteamPage /OrderPage 引用 Header image.png

页面和自定义组件生命周期

developer.harmonyos.com/cn/docs/doc…

@Component 1个File 中可以有多个

单独一个文件就可以被多个 File 引用。否则只能内部使用。

  • 自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。
  • @Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。
  • 只有被@Entry装饰的组件才可以调用页面的生命周期。

即被@Entry装饰的组件生命周期,生命周期接口:

  • onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。
  • onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。
  • onBackPress:当用户点击返回按钮时触发。

即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:

  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
  • aboutToDisappear:在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。

生命周期流程如下图所示,下图展示的是被@Entry装饰的组件(首页)生命周期。

image.png

@Builder装饰器:自定义构建函数。全局、局部,是否加 function 和作用域

developer.harmonyos.com/cn/docs/doc…

  // 局部自定义构建函数, 在 @Component struct 内。
  @Builder ItemCard(item: Item){
    Row({space: 10}){}
    }
   }
   
   使用:
   this.ItemCard(item)
   

// 全局自定义构建函数, 在文件内,在 @Component struct 外。
@Builder function ItemCard(item: Item){。。。}
    
    使用:ItemCard(item)
    

@Styles 通用样式函数定义 ,全局、局部 是否加 function 和作用域.只能定义公共属性 eg:with,

定义组件特有属性 使用继承 @Extend(Text) function abc(){...}

// 局部公共样式函数 、在 @Component struct 内。
@Styles fillScreen(){
.width('100%')
.height('100%')
.backgroundColor('#EFEFEF')
.padding(20)

// 全局 公共样式函数 、在 @Component struct 外。
@Styles function fillScreen(){
.width('100%')
.height('100%')
.backgroundColor('#EFEFEF')
.padding(20)

使用:
Column(){}.fillScreen()



// 继承模式,只能写在全局
@Extend(Text) function priceText(){
  .fontColor('#F36')
  .fontSize(18)
}

定义子组件和使用:

// Index.ets
import router from '@ohos.router';

@Entry
@Component
struct MyComponent {
  @State showChild: boolean = true;

  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageShow() {
    console.info('Index onPageShow');
  }
  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageHide() {
    console.info('Index onPageHide');
  }

  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onBackPress() {
    console.info('Index onBackPress');
  }

  // 组件生命周期
  aboutToAppear() {
    console.info('MyComponent aboutToAppear');
  }

  // 组件生命周期
  aboutToDisappear() {
    console.info('MyComponent aboutToDisappear');
  }

  build() {
    Column() {
      // this.showChild为true,创建Child子组件,执行Child aboutToAppear
      if (this.showChild) {//是否展示
        Child()//使用子组件
      }
      // this.showChild为false,删除Child子组件,执行Child aboutToDisappear
      Button('delete Child').onClick(() => {
        this.showChild = false;
      })
      // push到Page2页面,执行onPageHide
      Button('push to next page')
        .onClick(() => {
          router.pushUrl({ url: 'pages/Page2' });
        })
    }

  }
}

//定义子组件
@Component
struct Child {
  @State title: string = 'Hello World';
  // 组件生命周期
  aboutToDisappear() {
    console.info('[lifeCycle] Child aboutToDisappear')
  }
  // 组件生命周期
  aboutToAppear() {
    console.info('[lifeCycle] Child aboutToAppear')
  }

  build() {
    Text(this.title).fontSize(50).onClick(() => {
      this.title = 'Hello ArkUI';
    })
  }
}

单独一个文件被多处使用:


//另外的一个 File  src/main/ets/views/RouterItem.ets

@Component
export default struct RouterItem{
  r: RouterInfo
  i: number

  build(){
    Row(){}
  }
}


//另外的一个 File  CommonComponents.ets
@Component
export struct Header{
  private title: ResourceStr
  @State params: any = router.getParams()
  build(){
    // 标题部分。。。
  }
}




使用
import RouterItem from '../views/RouterItem'

import { Header } from '../common/components/CommonComponents';

@Builder
RouterList() {

Header({title: '文档列表'})//使用
  List({ space: 15 }) {
    ForEach(
      routers,(router, index) => {
        ListItem() {
          RouterItem({ r: router, i: index + 1 })//使用
        }
      }
    )
  }
}




引用传递:

值传递: