HarmonyOS 鸿蒙Next 子组件触发父组件中的方法

HarmonyOS 鸿蒙Next 子组件触发父组件中的方法

如何在子组件触发父组件中的方法;
 

3 回复

可以试试这种方法:

import hilog from '[@ohos](/user/ohos).hilog';
// import { HighSpeedItem } from '../bean/HighSpeedRseponse';

interface listItem {
  money: string
  text: string
  title: string
  data: string
}

class StringData {
  money: string
  text: string
  title: string
  data: string
  constructor(money: string,text: string, title: string, data: string) {
    this.money = money;
    this.text = text;
    this.title = title;
    this.data = data;
  }
}
class BasicDataSource implements IDataSource {
  private listeners: DataChangeListener[] = [];
  private originDataArray: StringData[] = [];
  public totalCount(): number {
    return 0;
  }
  public getData(index: number): StringData {
    return this.originDataArray[index];
  }
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      console.info('add listener');
      this.listeners.push(listener);
    }
  }
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      console.info('remove listener');
      this.listeners.splice(pos, 1);
    }
  }
  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    })
  }
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    })
  }
  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
    })
  }
  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
    })
  }
  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to);
    })
  }
}
class MyDataSource extends BasicDataSource {
  private dataArray: StringData[] = [];
  public totalCount(): number {
    return this.dataArray.length;
  }
  public getData(index: number): StringData {
    return this.dataArray[index];
  }
  public addData(index: number, data: StringData): void {
    this.dataArray.splice(index, 0, data);
    this.notifyDataAdd(index);
  }
  public pushData(data: StringData): void {
    this.dataArray.push(data);
    this.notifyDataAdd(this.dataArray.length - 1);
  }
  public reloadData(): void {
    this.notifyDataReload();
  }

  //删除全部数据
  public clear(): void {
    // this.dataArray = []
    // this.notifyDataReload();
    this.empty()
    this.refresh()
  }
  public empty(): void {
    this.dataArray = []
  }
  public refresh(): void {
    this.notifyDataReload();

  }
}


[@Entry](/user/Entry)
[@Component](/user/Component)
struct Index {
  private title: string = '我的优惠券'
  private data: MyDataSource = new MyDataSource();
  [@State](/user/State) currentIndex: number = 0
  [@State](/user/State) highSheepNum: number = 0
  [@State](/user/State) tollStationNum: number = 0
  [@State](/user/State) highSheepArray: highSheepItem[] = [
    new highSheepItem(0, "全部",'all',0,true),
    new highSheepItem(1, "商品",'all',0,false),
    new highSheepItem(2, "体验",'all',0,false),
  ]//高速//拥堵 type = 1  管制 type =2 事故 type = 3 施工 type = 4 其他 type = 5
  [@State](/user/State) listDate: listItem[] = [
    {
      money: '¥360',
      text: '满3500元立减',
      title: '限部分商品使用',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥250',
      text: '满2500元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥200',
      text: '满1800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥150',
      text: '满1300元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥80',
      text: '满800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥360',
      text: '满3500元立减',
      title: '限部分商品使用',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥250',
      text: '满2500元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥200',
      text: '满1800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥150',
      text: '满1300元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥80',
      text: '满800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥360',
      text: '满3500元立减',
      title: '限部分商品使用',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥250',
      text: '满2500元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥200',
      text: '满1800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥150',
      text: '满1300元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥80',
      text: '满800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥360',
      text: '满3500元立减',
      title: '限部分商品使用',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥250',
      text: '满2500元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥200',
      text: '满1800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥150',
      text: '满1300元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥80',
      text: '满800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥360',
      text: '满3500元立减',
      title: '限部分商品使用',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥250',
      text: '满2500元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥200',
      text: '满1800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥150',
      text: '满1300元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥80',
      text: '满800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥360',
      text: '满3500元立减',
      title: '限部分商品使用',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥250',
      text: '满2500元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥200',
      text: '满1800元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥150',
      text: '满1300元立减',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    },
    {
      money: '¥80',
      text: '满800元立减1',
      title: '适用于体验',
      data: '2024.02.23-2024.03.15'
    }
  ]
  aboutToAppear(): void {
    // 请求数据模拟
    this.init()
  }
  changeData(title:string){
    this.data.clear();
    let that = this;
    setTimeout(()=>{
      // hilog.info(0x0000, '数据1', '1')
      // hilog.info(0x0000, '数据2',JSON.stringify(that.listDate))
      // hilog.info(0x0000, '数据3',title)
      for (let i = 0; i <= that.listDate.length; i++) {
        hilog.info(0x0000, '数据4', JSON.stringify(that.listDate[i]))
        let listDate:listItem = that.listDate[i] as listItem;
        if(listDate?.title?.indexOf(title) !== -1){
          that.data.pushData(new StringData(listDate?.money,listDate?.text,listDate?.title,listDate?.data));
        }
      }
      this.data.reloadData();
      this.highSheepNum =  this.data.totalCount()
      hilog.info(0x0000, '组件加载2', JSON.stringify(this.data))

    },500)

  }
  build() {
    Column() {
      Tabs({ barPosition: BarPosition.Start }) {
        TabContent() {
          this.highSpeedBuilder()
        }.tabBar(this.TabRoadBuilder(0, '优惠券',this.highSheepNum))
        TabContent() {
          this.highSpeedBuilder()
        }.tabBar(this.TabRoadBuilder(1, '用于体验',this.tollStationNum))
      }
      .barWidth('100%')
      .scrollable(false)
      .vertical(false)
      .barHeight(40)
      .width('100%')
      .onChange((index: number) => {
        this.currentIndex = index;
        this.changeData('体验')

        if(index == 1){
          // this.getStationEvent()
        }else if(index == 2){
          // this.getServiceEvent()

          // this.getEventListIntroduc()
        }
      })
      .width('100%')
      .height('100%')
      .backgroundColor('#ffffff')
    }.width('100%').height('100%')

  }
  [@Builder](/user/Builder) TabRoadBuilder(index: number, name: string,num:number) {
    Column() {
      Text(name+'('+num+')')
        .fontColor(this.currentIndex === index ? '#015DFF' : '#999999')
        .fontSize(16)
        .fontWeight(this.currentIndex === index ? 500 : 400)
        .lineHeight(22)
        .margin({ top:6, bottom: 6 })

      Divider().strokeWidth(3).color(this.currentIndex === index ? '#015DFF' : '#999999').width(24)
    }.width('100%')
  }
  [@Builder](/user/Builder)
  highSpeedBuilder(){
    Column() {
      Flex({ justifyContent:FlexAlign.SpaceAround }) {
        ForEach(this.highSheepArray, (item: highSheepItem) => {
          replayComp({ item: item,changeData:this.changeData.bind(this)})
        }, (item: highSheepItem) => item.title)
      }.padding({left:10,right:10,bottom:12,top:12}).width('100%')
      Text(this.title)
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontFamily('Arial')
      Row() {
        TextInput({ placeholder: '请输入优惠码' })
          .width('75%')
          .fontColor(Color.Blue)
          .fontSize(14)
          .fontStyle(FontStyle.Italic)
          .fontWeight(FontWeight.Bold)
          .fontFamily('Arial')
          .placeholderColor(0x999999)
          .placeholderFont({ size: 16, weight: FontWeight.Medium, family: 'cursive', style: FontStyle.Italic })

        Button('筛选',{ type: ButtonType.Normal, stateEffect: true })
          .width('25%')
          .fontSize(14)
          .fontWeight(FontWeight.Medium)
          .backgroundColor('#cccccc')
          .borderRadius(5)
          .onClick(() => {


          })
      }
      .padding({ top: 35, bottom: 10})
      Row() {
        Text(`您有${this.highSheepNum}张优惠券可领用~`)
          .fontSize(12)
          .textAlign(TextAlign.End)
        Text('>')
      }
      .margin({bottom: 10})
      List({ space: 10 }) {
        LazyForEach(this.data, (item: listItem) => {
          ListItem() {
            Row() {
              Column() {
                Text(item.money)
                  .margin({top:20, bottom: 20})
                  .fontColor('#f9f4d7')
                  .borderRadius(5)
                Text(item.text)
                  .textAlign(TextAlign.Center)
                  .fontSize(12)
                  .fontColor('#f9f4d7')
                  .borderRadius(5)
              }
              .width('30%')
              .height(100)
              .backgroundColor('#fe6a48')
              Column() {
                Row() {
                  Text(item.title)
                    .textAlign(TextAlign.Start)
                    .margin({top: 15, left: -110, bottom: 40})
                }
                Row() {
                  Text(item.data)
                    .fontSize(10)
                    .margin({left: -5, right: 25})
                  Button('去使用', { type: ButtonType.Capsule })
                    .width('32%')
                    .height(20)
                    .fontSize(12)
                    .fontColor('#f6a200')
                    .backgroundColor('#cccccc')
                    .borderColor('#f6a200')
                }
              }
              .width('70%')
              .height(100)
              .backgroundColor('#fff')
            }.onAppear(()=>{
              // hilog.info(0x0000, '组件加载', item.title)
              // hilog.info(0x0000, '组件加载1', JSON.stringify(this.data.totalCount()))
            })
          }
        },(item: listItem) => item.title)
      }
    }
    .padding(12)
    .height('100%')
    .backgroundColor(0xF1F3F5)
  }
  [@Builder](/user/Builder)
  tollStationsBuilder(){
    Column(){
      Text('测试')
    }
  }
  init(){
    for (let i = 0; i < this.listDate.length; i++) {
      // hilog.info(0x0000, '循环',this.listDate[i].title)
      this.data.pushData(new StringData(this.listDate[i].money,this.listDate[i].text,this.listDate[i].title,this.listDate[i].data));
    }
    this.highSheepNum =  this.data.totalCount()
    this.Statistics()
    // console.log(JSON.stringify(this.data),'[Log]')
  }
  Statistics(){
    let controlNum:number = 0;//商品
    let congestionNum:number = 0;//体验
    for(let i=0;i < this.listDate.length;i++){
      if(this.listDate[i].title?.indexOf('商品') !== -1){
        controlNum++
      }
      if(this.listDate[i].title?.indexOf('体验') !== -1){
        congestionNum++
      }
    }
    for(let j=0;j < this.highSheepArray.length;j++){
      if(this.highSheepArray[j].title == '全部'){
        this.highSheepArray[j].number = this.highSheepNum
      }
      if(this.highSheepArray[j].title == '商品'){
        this.highSheepArray[j].number = controlNum
      }
      if(this.highSheepArray[j].title == '体验'){
        this.highSheepArray[j].number = congestionNum
      }

    }
  }
}
[@Component](/user/Component)
struct replayComp {
  [@ObjectLink](/user/ObjectLink) item: highSheepItem
  [@State](/user/State) highSheepCur: number = 0
  [@State](/user/State) selectedFontColor: string = '#015DFF'
  changeData = (title:string) => {}
  build() {
    Column(){
      Text(this.item.title+'('+this.item.number+')')
        .fontSize(14)
        .fontColor(this.highSheepCur == this.item.index?'#015DFF':'#999999')
        .fontWeight(this.highSheepCur === this.item.index ? 500 : 400)
        .margin({bottom:6})
      Divider().strokeWidth(3).color(this.highSheepCur === this.item.index ? this.selectedFontColor : Color.White).width(24)

    }.onClick(() =>{
      this.highSheepCur = this.item.index;
      this.changeData(this.item.title)
      // 1、想在这里面触发父级的方法changeData 怎么触发
      // 2、点击的时候怎么能做到切换样式
    })
  }
}


[@Observed](/user/Observed)
class highSheepItem {
  index: number
  title: string
  code: string
  number: number
  ischeck:boolean
  constructor(index: number, title: string, code: string,number:number,ischeck:boolean) {
    this.index = index
    this.title = title
    this.code = code
    this.number = number
    this.ischeck = ischeck
  }

更多关于HarmonyOS 鸿蒙Next 子组件触发父组件中的方法的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


深色代码主题
复制
v2 里面有[@Event](/user/Event),或者自定义Controller ,来回传。

在HarmonyOS鸿蒙系统中,子组件触发父组件中的方法可以通过事件机制来实现。具体步骤如下:

  1. 定义事件:在父组件中定义一个自定义事件,该事件包含需要传递给父组件的数据。

  2. 子组件触发事件:在子组件中,通过调用父组件提供的接口或方法(如通过$emit)来触发该自定义事件,并传递必要的数据。

  3. 父组件监听事件:在父组件中,通过事件监听机制来捕获子组件触发的事件。在事件处理函数中,调用父组件内部的方法,并处理传递过来的数据。

  4. 数据与方法绑定:确保父组件中的方法已经正确绑定到事件处理函数上,同时确保子组件能够正确触发并传递事件。

示例代码(伪代码形式):

// 父组件
@Entry
@Component
struct Parent {
    @State data: string = "";

    @Builder
    build() {
        Column() {
            Child(@Event(eventName) onChildEvent(event: CustomEvent) {
                this.data = event.data;
                this.parentMethod();
            })
        }
    }

    parentMethod() {
        console.log("Parent method called");
    }
}

// 子组件
@Component
struct Child {
    @Event(eventName) emitEvent: (event: CustomEvent) => void;

    triggerParent() {
        let event = new CustomEvent("eventName", { data: "Hello from Child" });
        this.emitEvent(event);
    }
}

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部