HarmonyOS 鸿蒙Next中HMRouter相关问题!

HarmonyOS 鸿蒙Next中HMRouter相关问题! 问题是:在A中点击按钮切换B、C页面时,在这两个切换的页面中,有一个共用组件D,组件D里面有个值,想要实现,D组件这个值,在B、C页面切换的过程中,能保持同步,有什么好的办法实现吗?

我试过,给切换按钮的布尔值加一个watch,每次改变,就让num重新赋值,但是不中!

代码如下:

这是主页面A:

import { HMRouter } from "@hadss/hmrouter"
import { ComB } from "./ComB"
import { ComC } from "./ComC"

@HMRouter({ pageUrl: 'ComA' })
@Component
export struct ComA {
  @State isChange: boolean = false

  build() {
    Column() {
      Button('切换按钮').onClick(() => {
        this.isChange = !this.isChange
      })

      if (this.isChange) {
        ComB()
      } else {
        ComC()
      }
    }
  }
}

子页面B:

import { ComD } from "./ComD"

@Component
export struct ComB {
  build() {
    Column() {
      Text('页面B')
      ComD()
    }.width('100%').height(200).backgroundColor('#857')
  }
}

子页面C

import { ComD } from "./ComD"

@Component
export struct ComC {

  build() {
    Column() {
      Text('页面C')

      ComD()
    }.width('100%').height(100).backgroundColor('#c0c0c0')
  }
}

子页面B和子页面C的公共组件D

其中加了一个页面展示的监听,每次这个D组件展示的时候,就重新给num赋值为1

问题就是,在切换B、C页面时,这个num就会等于0,并不会维持之前的值,因为刚进入页面的时候,num被赋值为1,在切换之后,num就等于0了。

有一个解决的办法,但是我觉得不完美,其实这个赋值的位置是一个方法,这个方法会返回一个number,再重新赋值,现在的解决办法,就是定义这个num的时候,默认值不给0,直接写这个方法名字,就可以实现公共组件D中的num值保持同步。

import { HMLifecycleState, HMPopInfo, HMRouter, HMRouterMgr } from "@hadss/hmrouter"

@Component
export struct ComD {
  @State num: number = 0

  aboutToAppear(): void {
    HMRouterMgr.getCurrentLifecycleOwner()?.addObserver(HMLifecycleState.onShown, (ctx) => {
      this.num = 1
    })
  }

  build() {
    Column() {
      Text(`页面D${this.num}`)
    }
  }
}

更多关于HarmonyOS 鸿蒙Next中HMRouter相关问题!的实战教程也可以访问 https://www.itying.com/category-93-b0.html

11 回复

可以再试下以下两种方式:

方式一:通过[@Link装饰器](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-link#概述)实现父子组件双向同步

@HMRouter({ pageUrl: 'ComA' })
@Component
export struct ComA {
  @State isChange: boolean = false
  @State num: number = 0

  build() {
    Column() {
      Button('切换按钮').onClick(() => {
        this.isChange = !this.isChange
      })
      if (this.isChange) {
        ComB({
          num: $num
        })
      } else {
        ComC({
          num: $num
        })
      }
    }
  }
}

@Component
export struct ComB {
  [@Link](/user/Link) num:number;

  build() {
    Column() {
      Text('页面B')
      ComD({
        num:$num
      })
    }
    .width('100%')
    .height(200)
    .backgroundColor('#857')
  }
}

@Component
export struct ComD {
  [@Link](/user/Link) num: number;

  build() {
    Column() {
      Text(`页面D${this.num}`)
        .onClick(() => {
          let tmp:number = this.num + 1;
          this.num = tmp
        })
    }
  }
}

方式二:单例类实现数据共享

@ObservedV2
export class GetNum{
  private static instance:GetNum;
  @Trace
  private num:number = 0;
  private constructor() {
  }
  public static getInstance(){
    if (!GetNum.instance) {
      GetNum.instance = new GetNum();
    }
    return GetNum.instance
  }
  public getNum():number{
    return this.num;
  }
  public setNum(num: number) {
    this.num = num;
  }
}


@Component
export struct ComD {
  num: GetNum = GetNum.getInstance()

  build() {
    Column() {
      Text(`页面D${this.num.getNum()}`)
        .onClick(() => {
          let tmp: number = this.num.getNum() + 1;
          this.num.setNum(tmp)
        })
    }
  }
}

更多关于HarmonyOS 鸿蒙Next中HMRouter相关问题!的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


感谢感谢!明白了!通透!!!一下想通了!

可以通过AppStorage实现页面间的数据同步,

对于不同页面之间的参数传递,可以使用AppStorage实现。AppStorage是应用全局的UI状态存储,与应用的进程绑定,由UI框架在应用程序启动时创建。使用SubscribedAbstractProperty可以读取、设置从AppStorage/LocalStorage同步属性的数据。

如:

@Component
export struct ComD {
  @State num: SubscribedAbstractProperty<number> = AppStorage.link('ComDNum');

  build() {
    Column() {
      Text(`页面D${this.num.get()}`)
        .onClick(() => {
          let num: number = this.num.get() + 1
          this.num.set(num)
        })
    }
  }
}

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17,

谢谢,这也是个办法~想看看有没有更好的解决办法~,

更好的方式?你是想要什么样的实现?

  1. 可以通过AppStorage实现数据同步

  2. 为共用组件D创建一个静态的控制器,全局唯一来实现控制,对组件的操作都通过控制器来操作,数据传递也通过控制器来处理

MVVM模式-状态管理(V1)-学习UI范式状态管理-UI开发 (ArkTS声明式开发范式)-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者

有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html

可以的可以的!!!感谢~,

HMRouter是鸿蒙Next中基于ArkTS的声明式路由框架,通过@Router装饰器实现页面导航与参数传递。支持静态路由注册和动态路由配置,提供页面跳转、返回、传参等基础功能。其生命周期与PageAbility联动,可通过RouterContext管理导航栈。常见问题包括路由未注册导致的跳转失败或参数解析异常,需检查路由表配置与参数类型匹配。

在HarmonyOS Next中,要实现组件D在B、C页面切换时保持状态同步,建议使用AppStorage或LocalStorage进行状态管理。通过将组件D中的num值存储在共享存储中,可以确保其在页面切换过程中保持一致。

修改组件D,将num定义为AppStorage中的属性:

import { AppStorage } from '@ohos/data'

@Component
export struct ComD {
  @StorageLink('num') num: number = AppStorage.Get<number>('num') || 0

  build() {
    Column() {
      Text(`页面D${this.num}`)
    }
  }
}

在页面A中初始化该值:

AppStorage.SetOrCreate<number>('num', 0)

这样,无论B、C页面如何切换,组件D中的num值都会从AppStorage中读取和更新,保持同步。无需监听页面生命周期或手动重置值。

回到顶部