在代码结构方面,首先导入了RNInstance核心类,这是React Native在鸿蒙平台上的实例管理对象。从本地模块导入BaseRN和LoadManager,BaseRN是基础的React Native渲染组件,LoadManager负责RN实例的加载和管理。MetroBaseRN是专门用于Metro开发服务器环境的渲染组件。

emitter事件发射器的导入提供了跨组件通信能力,这是鸿蒙系统中实现事件驱动架构的重要组件。Details、PrecreateRN、MultiSurface、SandBoxApp等本地组件的导入构成了完整的页面导航体系。

@Component装饰器声明这是一个自定义组件结构,export default struct Goods定义了商品模块的主组件。这种基于结构体的组件定义方式是鸿蒙ArkTS语言的特色,提供了更好的类型安全和运行时性能。

组件内部定义了private instance: RNInstance = LoadManager.cpInstance,通过LoadManager获取共享的RN实例,这种实例复用机制有助于优化内存使用和提升性能。

bundlePath设置为’bundle/cp/goods.harmony.bundle’,这是商品模块的bundle文件路径。moduleName设置为’Goods’,标识了模块的唯一名称。


使用自定义组件

​ 在entry/src/main/cpp/ButtonView目录下创建了自定义组件ButtonView,该目录下包括了组件的所有代码。

​ 在src/main/cpp/SampleTurboModulePackage.cpp方法中添加自定义组件的映射:

请添加图片描述

​ 在React Native侧的basic/ButtonView.tsx中定义了ButtonViewJSI接口:

请添加图片描述

GoodsMainPage.tsx中使用自定义组件:
请添加图片描述


请添加图片描述

@StorageLink(‘isMetroAvailable’) isMetroAvailable: boolean = false,这个装饰器创建了一个与AppStorage双向绑定的状态变量,用于检测Metro开发服务器是否可用。

@Consume(‘pagePathsGoods’) pagePathsGoods: NavPathStack,这个装饰器消费了AppStorage中的页面路径堆栈,实现了全局的导航状态管理。

@Builder装饰器定义了PageMap函数,这是一个页面映射构建器,根据传入的页面名称和参数渲染对应的页面组件。这种设计模式实现了页面路由的集中管理。

import { RNInstance } from '@rnoh/react-native-openharmony';
import { BaseRN, LoadManager } from '../rn';
import { MetroBaseRN } from '../rn/MetroBaseRN'
import emitter from '@ohos.events.emitter';
import Details from "./Details";
import PrecreateRN from './PrecreateRN';
import { MultiSurface } from './MultiSurface';
import SandBoxApp from './SandboxBundle';

@Component
export default struct Goods {
  private instance: RNInstance = LoadManager.cpInstance;
  private bundlePath = 'bundle/cp/goods.harmony.bundle';
  private moduleName = 'Goods';
  @StorageLink('isMetroAvailable') isMetroAvailable: boolean = false;
  @Consume('pagePathsGoods') pagePathsGoods: NavPathStack;

  @Builder
  PageMap(name: string, param: string) {
    if (name === 'Details') {
      Details({ name: param });
    } else if (name === 'PrecreateRN') {
      PrecreateRN();
    } else if (name === 'MultiSurface') {
      MultiSurface();
    } else if (name === 'Sandbox') {
      SandBoxApp();
    } else {
      Text('无效页面');
    }
  }

  aboutToAppear() {
    emitter.on({ eventId: 1 }, (eventData) => {
      if (eventData.data) {
        console.log('[TurboModule] param = ' + eventData.data['param']);
        const path: string = eventData.data['param'];
        if (path === "pages/Details") {
          this.pagePathsGoods.pushPath({ name: "Details", param: "details1" });
        } else if (path === "pages/Details2") {
          this.pagePathsGoods.pushPath({ name: "Details", param: "detail2" });
        } else if (path === "pages/DetailsMultiInstance") {
          this.pagePathsGoods.pushPath({ name: "DetailsMultiInstance", param: "MultiInstance" });
        } else if (path === "pages/PrecreateRN") {
          this.pagePathsGoods.pushPath({ name: "PrecreateRN" });
        } else if (path === "pages/MultiSurface") {
          this.pagePathsGoods.pushPath({ name: "MultiSurface" });
        } else if (path === "pages/Sandbox") {
          this.pagePathsGoods.pushPath({ name: "Sandbox" });
        }
        // this.pagePathsGoods.pushPath({ name: "DetailsMultiInstance", param: "MultiInstance" })
      }
    });
  }

  aboutToDisappear() {
    emitter.off(1);
  }

  build() {
    Navigation(this.pagePathsGoods) {
      if (this.isMetroAvailable) {
        MetroBaseRN({
          moduleName: this.moduleName,
        }).align(Alignment.Top).margin({ top: 0 })
      } else if (this.instance) {
        BaseRN({
          rnInstance: this.instance,
          moduleName: this.moduleName,
          bundlePath: this.bundlePath,
        }).align(Alignment.Top).margin({ top: 0 })
      }
    }
    .navDestination(this.PageMap)
    .hideTitleBar(true)
    .hideToolBar(true)
  }
}

当name为’Details’时,渲染Details组件,传入name参数。这种参数传递机制确保了页面间数据的一致性。

当name为’PrecreateRN’时,渲染PrecreateRN组件。这个组件可能负责预创建RN实例的功能,用于优化应用启动性能。

当name为’MultiSurface’时,渲染MultiSurface组件。这个组件可能支持多个RN表面的渲染,适用于复杂的界面场景。

当name为’Sandbox’时,渲染SandBoxApp组件,提供沙箱环境下的应用运行能力。

当name不匹配任何已知页面时,显示’无效页面’的文本提示,提供了友好的错误处理机制。

aboutToAppear生命周期函数在组件即将显示时执行。通过emitter.on({ eventId: 1 }, (eventData) => {…})注册事件监听器,监听事件ID为1的事件。

当接收到事件数据时,通过console.log输出调试信息,记录接收到的参数值。

从eventData.data[‘param’]获取路径参数,这个参数决定了要跳转的目标页面。

当path为"pages/Details"时,向pagePathsGoods推送Details页面路径,附带"details1"参数。这种参数化路由设计支持灵活的页面导航。

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐