【鸿蒙】HarmonyOS NEXT星河入门到实战8-自定义组件-组件通信

目录

1、模块化语法

1.1 模块化基本认知

1.2 默认导出和导入

1.2.1 在ets下新建tools目录

1.2.2 在tools下新建moduls.ets文件

1.2.3 index.ets

1.3 按需导出和导入

1.4 全部导入

2、自定义组件 -基础

2.1 自定义组件 - 基本使用

 2.2 自定义组件 -通用样式

2.2.1 ets下新建components文件夹

2.2.2 components新建HelloCom.ets

2.2.3 Index.ets

2.3 自定义组件 -成员函数变量

3、@BuilderParam

3.1 @BuilderParam 传递UI

3.2  多个 @BuilderParam 参数

4、 状态管理

4.1 状态管理概述

4.2 @ State 自己的状态

4.3 @Prop -父子单向

4.4 掘金评论案例

4.4.1 头部组件

4.4.1.1 在ets/components下新建InfoTop.ets

4.4.1.2 Index.ets

4.4.2 评论案例 - List列表组件的使用

4.4.2.1 List列表基本使用

 4.4.2.2 中间评论列表

4.4.2.2.1 在components下新增InfoItem.ets

4.4.2.2.2 Index .ets

4.4.3 底部评价

4.4.3.1 IconFont的使用

4.4.3.1.1 ets\fonts下存放下载的文件

4.4.3.1.2 注册字体&使用字体

4.4.3.2  在components下新增InfoBottom.ets

4.4.3.3  Index .ets

4.4.4 列表渲染

4.4.4.1 准备数据

4.4.4.2 列表渲染完成

4.4.4.3 点赞

4.4.4.4 添加评论

4.4.4.5 评论排序

4.5 @Link双向同步 

 4.6 @Provide \@Consume后代组件

4.7 @ Observed &@ObjectLink嵌套对象数组属性变化


前言:自定义组件-组件通信(模块化语法)、自定义组件、传递UI、状态管理

1、模块化语法

1.1 模块化基本认知

1.2 默认导出和导入

1.2.1 在ets下新建tools目录

 

1.2.2 在tools下新建moduls.ets文件

interface  Person {
  name: string
  age: number
}

let num: number = 10
let person: Person ={
  name: '春天的菠菜',
  age: 18
}
// 默认导出(导出一个值)
export  default num

1.2.3 index.ets

导入进来  import 导入进来新取的名称  from 路径(相对路径)

import window from '@ohos.window';
// 相对路径
import myNum from '../tools/moduls'

@Extend(Text)
function textExtend(){
  .fontSize(20)
  .fontWeight(700)
  .backgroundColor(Color.Green)
  .padding(10)
  .margin(5)
}



@Entry
@Component
struct Index {
  @State message: string = '@春天的菠菜';

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }

  build() {
   Column(){
     Text('来自tools/modlus 模块的值:'+ myNum)
       .textExtend()
   }
   .width('100%').height(100)
  }
}

1.3 按需导出和导入

 tools下新建/module3.ets

// 按需导出
// 多个特性, 逐个 export 按需导出
// export let name1: string = '刘备'
// export let price: number = 9.98
// export let sayHi = () => {
//   console.log('打招呼')
// }

let name1: string = '刘备'
let name2: string = '张飞'
let name3: string = '关羽'

let price: number = 9.98
let price2: number = 10.1

let sayHi = () => {
  console.log('打招呼')
}
let run = () => {
  console.log('跑步')
}

// 一次性将多个特性, 进行导出
export {
  name1, name2, name3,
  price, price2,
  sayHi, run
}

import window from '@ohos.window';
// 相对路径
import myNum from '../tools/moduls'
import { name1, price, sayHi }from '../tools/module3'

sayHi()

@Extend(Text)
function textExtend(){
  .fontSize(20)
  .fontWeight(700)
  .backgroundColor(Color.Green)
  .padding(10)
  .margin(5)
}



@Entry
@Component
struct Index {
  @State message: string = '@春天的菠菜';

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }

  build() {
   Column(){
     Text('来自tools/modlus 模块的值:'+ myNum)
       .textExtend().margin(5)
     Text('来自tools/module3 模块的值:'+ name1 +'**' + price )
       .textExtend()
   }
   .width('100%').height(100)
  }
}

1.4 全部导入

2、自定义组件 -基础

2.1 自定义组件 - 基本使用

1、无@Entry 2、 struct 后面自定义名称

import window from '@ohos.window';


@Extend(Text)
function textExtend(){
  .fontSize(20)
  .fontWeight(700)
  .backgroundColor(Color.Green)
  .padding(10)
  .margin(5)
}



@Entry
@Component
struct Index {
  @State message: string = '@春天的菠菜';

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }

  build() {
    Column() {
      MyHeader()
      MyMain()
      MyFooter()
    }
  }
}


@Component
struct MyCom {
  @State count: number = 1
  build() {
    Row() {
      Text(this.count.toString())
        .fontColor(Color.White)
        .margin(10)
      Button('按钮')
        .onClick(() => {
          this.count++
        })
    }
  }
}

@Component
struct MyHeader {
  build() {
    Row() {
      Text('我是头部')
        .fontColor(Color.White)
    }
    .width('100%')
    .height(50)
    .backgroundColor(Color.Brown)
  }
}

@Component
struct MyMain {
  build() {
    Column() {
      // 将相同的业务逻辑, 封装成一个通用的组件
      MyCom()
      MyCom()
      MyCom()
    }
    .layoutWeight(1)
    .width('100%')
    .backgroundColor(Color.Gray)
  }
}

@Component
struct MyFooter {
  build() {
    Row() {
      Text('我是底部')
    }
    .width('100%')
    .height(50)
    .backgroundColor(Color.Green)
  }
}

 2.2 自定义组件 -通用样式

2.2.1 ets下新建components文件夹

2.2.2 components新建HelloCom.ets

@Preview
@Component
export struct HelloCom {
  build() {
    Row() {
      Text('自定义组件')
      Button('按钮')
    }
    .width(200)
    .height(50)
    .backgroundColor(Color.Orange)
  }
}

2.2.3 Index.ets

import window from '@ohos.window';
import { HelloCom } from '../components/HelloCom'

@Extend(Text)
function textExtend(){
  .fontSize(20)
  .fontWeight(700)
  .backgroundColor(Color.Green)
  .padding(10)
  .margin(5)
}



@Entry
@Component
struct Index {
  @State message: string = '@春天的菠菜';

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }

  build() {
    Column() {
      HelloCom()
        .width(250)
        .height(60)
        .backgroundColor(Color.Gray)
        .onClick(() => {
          AlertDialog.show({
            message: '测试点击'
          })
        })
    }
  }
}

2.3 自定义组件 -成员函数变量

带=符号的可以外部传参

import window from '@ohos.window';




@Entry
@Component
struct Index {
  @State message: string = '@春天的菠菜';

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }

  build() {
    Column() {
      MyPanel({
        title: '我的订单',
        extra: '全部订单',
        getMore() {
          AlertDialog.show({
            message: '点击了全部订单'
          })
        }
      })
      MyPanel({
           title: '小米有品众筹',
        extra: '七款众筹中',
        getMore() {
          AlertDialog.show({
            message: '点击了众筹'
          })
        }
  }
      )

    }
    .width('100%').height('100%')
    .backgroundColor('#ccc')
    .padding(20)
  }
}

@Component
struct MyPanel {
  // 成员变量 -数据
  title: string = '默认的大标题'
  extra: string = '查看更多'

  // 成员变量 -函数 可以传入覆盖
  getMore = () =>{
    AlertDialog.show({
      message: '查看更多'
    })

  }

  // 成员函数  --  不可以外部传入覆盖
  sayHi (){
    AlertDialog.show({
      message: '打招呼 你好'
    })
}

  build() {
    Column(){
      Row(){
        Text(this.title)
          .fontSize(18)
        Text(this.extra)
          .fontSize(18)
          .onClick( () => {
            this.getMore()
          })

      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceBetween)

      Row(){
        Text('内容部分')
          .fontSize(18)
        Button('按钮')
          .onClick(() => {
            this.sayHi()
          })
      }
      .padding(20)

    }
    .width('100%').height(200)
    .margin({bottom: 20})
    .borderRadius(10)
    .padding(10)
    .backgroundColor(Color.White)
    
  }
}

3、@BuilderParam

3.1 @BuilderParam 传递UI

import window from '@ohos.window';



@Component
struct  SonCom {
  // 1、 定义构建函数
  @BuilderParam ContentBuilder: () => void = this.defaultBuilder
  @Builder
  defaultBuilder () {
    Text('默认的内容')
  }
  build() {
  //   2、 使用构建函数,构建结构
    Column(){
      this.ContentBuilder()
    }



  }
}

@Entry
@Component
struct Index {
  @State message: string = '@春天的菠菜';

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }

  build() {
    Column() {
      SonCom() {
        Button('传入的结构')
      }
    }


  }
}

练习

import window from '@ohos.window';



@Entry
@Component
struct Index {
  @State message: string = '@春天的菠菜';

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }

  build() {
    Column() {
      MyPanel({
        title: '我的订单',
        extra: '全部订单',
        getMore() {
          AlertDialog.show({
            message: '点击了全部订单'
          })
        }
      }) {
        Text('我是订单相关的文本')
      }
      MyPanel({
        title: '小米有品众筹',
        extra: '七款众筹中',
        getMore() {
          AlertDialog.show({
            message: '点击了众筹'
          })
        }
      }) {
        Button('我是小米众筹的按钮')
      }

    }
    .width('100%').height('100%')
    .backgroundColor('#ccc')
    .padding(20)
  }
}

@Component
struct MyPanel {
  // 成员变量 -数据
  title: string = '默认的大标题'
  extra: string = '查看更多'

  // 成员变量 -函数 可以传入覆盖
  getMore = () =>{
    AlertDialog.show({
      message: '查看更多'
    })

  }

  // 成员函数  --  不可以外部传入覆盖
  sayHi (){
    AlertDialog.show({
      message: '打招呼 你好'
    })
  }
  // 1、 定义构建函数
  @BuilderParam ContentBuilder: () => void = this.defaultBuilder
  @Builder
  defaultBuilder () {
    Text('默认的内容')
  }
  build() {
    Column(){
      Row(){
        Text(this.title)
          .fontSize(18)
        Text(this.extra)
          .fontSize(18)
          .onClick( () => {
            this.getMore()
          })

      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceBetween)

      Row(){
      //   这里结构不能写死,需要通过BUilderParam来进行构建
        this.ContentBuilder()
      }
      .padding(20)

    }
    .width('100%').height(200)
    .margin({bottom: 20})
    .borderRadius(10)
    .padding(10)
    .backgroundColor(Color.White)

  }
}

3.2  多个 @BuilderParam 参数

import window from '@ohos.window';

@Component
struct MyCard {
  @BuilderParam tBuilder: () => void = this.tDefaultBuilder
  @BuilderParam cBuilder: () => void = this.cDefaultBuilder
  @Builder tDefaultBuilder () {
    Text('我是默认的大标题')
  }
  @Builder cDefaultBuilder () {
    Text('我是默认的内容')
  }

  build() {
    // 卡片组件
    Column() {
      // 标题部分
      Row() {
        this.tBuilder()
      }
      .height(30)
      .width('100%')
      .border({ color: '#ccc', width: { bottom: 1 }})
      .padding({ left: 10 })
      // 内容部分
      Row() {
        this.cBuilder()
      }
      .width('100%')
      .padding(10)
    }
    .width('100%')
    .height(100)
    .backgroundColor(Color.White)
    .borderRadius(10)
    .justifyContent(F
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春天的菠菜

一毛两毛也是动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值