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


在企业级移动应用开发中,电子合同系统因其安全性要求高、数据可视化需求强,成为技术选型的重要考量对象。本文将深入解读一个基于 React Native 开发的电子合同个人统计组件代码片段,剖析其架构设计、组件化策略以及在鸿蒙系统上的跨端实现考量。

数据流

代码实现了一个 EContractStatsPersonal 函数式组件,采用了 React 的函数组件模式和 Hooks 系统。这种模式在 React Native 和鸿蒙系统的 ArkTS 中都有良好的支持,为跨端开发提供了便利。

const EContractStatsPersonal: React.FC = () => {
  const onExport = () => Alert.alert('个人统计', '已导出个人签署统计报告 PDF');

  return (
    <SafeAreaView style={styles.container}>
      {/* 组件内容 */}
    </SafeAreaView>
  );
};

组件结构清晰,主要包含头部、签署概览、最近签署和操作栏四个部分。这种模块化的结构设计使得代码易于维护和扩展,同时也为跨端开发提供了便利。

图标资源

代码使用了 Base64 编码的图标资源,这种方式在跨端开发中具有显著优势:

const ICONS_BASE64 = {
  chart: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
  doc: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
  exportx: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
};

使用 Base64 编码的图标可以避免网络请求,提高应用加载速度,同时减少对外部资源的依赖,这在鸿蒙系统的跨端开发中尤为重要,因为它可以确保图标在不同平台上的一致性显示。


响应式

代码使用了 Flexbox 布局模型,这是 React Native 和鸿蒙系统 ArkTS 都支持的布局方式,为跨端开发提供了便利:

<View style={styles.header}>
  <Text style={styles.title}>电子合同 · 个人统计</Text>
  <View style={styles.headerIcons}>
    <Image source={{ uri: ICONS_BASE64.chart }} style={styles.headerIconImg} />
    <Text style={styles.headerEmoji}>📊</Text>
  </View>
</View>

通过 flexDirectionjustifyContentalignItems 等属性,实现了灵活的布局结构,确保应用在不同尺寸的设备上都能有良好的显示效果。


代码实现了签署概览的进度条展示,通过动态设置 width 属性实现进度条的长度:

<View style={styles.barRow}>
  <Text style={styles.barLabel}>已签</Text>
  <View style={[styles.bar, { width: '60%' }]} />
  <Text style={styles.barMeta}>24</Text>
</View>

这种方式在 React Native 和鸿蒙系统中都能很好地工作,为用户提供了直观的数据可视化效果。

样式

代码使用了 React Native 内置的 StyleSheet 进行样式管理,这是一种性能优化的最佳实践:

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#f8fffb' },
  header: { padding: 16, backgroundColor: '#ffffff', borderBottomWidth: 1, borderBottomColor: '#d1fae5', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
  // 其他样式
});

通过 StyleSheet.create 创建的样式对象,会被 React Native 转换为原生样式,提高渲染性能。在鸿蒙系统的跨端开发中,这种样式管理策略同样适用,但需要根据鸿蒙系统的样式 API 进行适当调整。


事件处理机制

代码实现了导出功能的事件处理:

const onExport = () => Alert.alert('个人统计', '已导出个人签署统计报告 PDF');

这种基于回调函数的事件处理方式,在 React Native 和鸿蒙系统中都能很好地工作。通过 Alert.alert 提供用户反馈,确保了操作的可感知性。

滚动视图

代码使用了 ScrollView 组件来实现内容的滚动:

<ScrollView style={styles.content}>
  {/* 内容 */}
</ScrollView>

在鸿蒙系统上,ScrollView 的滚动性能需要特别关注。由于鸿蒙系统对原生组件的渲染速度较快,但对 JavaScript 执行的性能要求较高,因此应尽量减少 ScrollView 中的复杂计算,确保滚动的流畅性。


React Native 的核心组件(如 SafeAreaViewViewTextImageTouchableOpacityScrollView 等)在鸿蒙系统上都有对应的实现,但在某些属性和行为上可能存在差异。例如,SafeAreaView 的安全区域计算、Image 组件的加载策略等,都需要在鸿蒙系统上进行测试和优化。

图标资源

代码使用了 Base64 编码的图标资源和 Emoji 作为图标,这种方式在跨端开发中具有显著优势:

  1. Base64 图标:避免了网络请求,提高了应用加载速度,同时确保了图标在不同平台上的一致性显示。
  2. Emoji 图标:使用系统内置的 Emoji,减少了应用包大小,同时确保了在不同平台上的一致性显示。

在鸿蒙系统上,这种图标资源处理方式同样适用,但需要注意 Emoji 的显示差异,确保在不同平台上的一致性。

在鸿蒙系统上,React Native 应用的性能优化需要考虑以下几点:

  1. 渲染性能:鸿蒙系统对原生组件的渲染速度较快,但对 JavaScript 执行的性能要求较高。因此,应尽量减少 JavaScript 线程的计算负担,将复杂的计算逻辑移至原生层。

  2. 内存管理:电子合同系统通常会加载大量文档和图表,内存消耗较大。在鸿蒙系统上,需要特别注意内存的分配和释放,避免内存泄漏。

  3. 网络请求:电子合同系统的网络请求频繁,应合理使用缓存策略,减少网络请求次数,提高应用响应速度。


类型安全

代码使用了 TypeScript 进行类型定义,这不仅提高了代码的可读性,也为跨端开发提供了类型安全保障。在鸿蒙系统的 ArkTS 环境中,类型系统的一致性尤为重要,它确保了数据在不同平台间传递时的准确性。

代码的结构清晰,将组件逻辑、样式等分离,便于维护和扩展。这种模块化设计在跨端开发中尤为重要,因为它使得平台特定的代码修改可以被隔离在最小范围内。

代码中使用了 Alert 进行用户反馈,这是一种简单有效的错误处理方式。在实际开发中,还应考虑添加更全面的错误处理机制,如网络请求错误、数据解析错误等,以提高应用的稳定性。


代码展示了组件化开发的最佳实践:

  1. 单一职责原则EContractStatsPersonal 组件只负责电子合同个人统计的展示和交互,职责清晰。

  2. 模块化结构:组件内部结构清晰,分为头部、签署概览、最近签署和操作栏四个部分,便于维护和扩展。

  3. 样式分离:使用 StyleSheet.create 将样式与组件逻辑分离,提高了代码的可读性和可维护性。

代码使用了 Flexbox 布局模型,实现了灵活的响应式布局:

  1. Flexbox 布局:通过 flexDirectionjustifyContentalignItems 等属性,实现了灵活的布局结构。

  2. 动态宽度:通过动态设置 width 属性,实现了进度条的长度变化,为用户提供了直观的数据可视化效果。

  3. 使用核心组件:优先使用 React Native 的核心组件,这些组件在鸿蒙系统上有较好的兼容性。

  4. 图标资源处理:使用 Base64 编码的图标和 Emoji,确保在不同平台上的一致性显示。

  5. 性能优化:针对不同平台的性能特点,进行有针对性的优化。

  6. 用户体验:确保在不同平台上的用户体验一致性,包括交互方式、视觉效果等。

  7. 代码质量:使用 TypeScript 进行类型定义,提高代码的可读性和可维护性。

通过对这个 React Native 电子合同个人统计组件代码片段的深入解读,我们可以看到,一个优秀的跨端应用需要在架构设计、组件化策略、性能优化等多个方面进行精心考量。特别是在 React Native 与鸿蒙系统的跨端开发中,需要充分了解两个平台的特性,才能开发出性能优异、用户体验一致的应用。

在未来的开发中,我们还可以探索更多技术方案,如使用 Redux 或 MobX 进行状态管理、使用 React Navigation 进行路由管理、使用 Expo 进行快速开发等,进一步提高开发效率和应用质量。同时,也需要密切关注鸿蒙系统的发展动态,及时调整开发策略,以适应新的技术要求。


电子合同统计类页面是企业级应用的典型场景,其核心诉求是数据可视化展示、结构化列表呈现、操作按钮的功能化交互,同时对UI的专业性、数据层级和操作引导性有极高要求。本文以一个完整的 React Native 电子合同个人统计页面为例,拆解其数据可视化布局、结构化信息展示、功能按钮设计的核心实现,并深入探讨该页面向鸿蒙(HarmonyOS)生态迁移的技术要点,为跨端企业级应用开发提供可落地的实践参考。

该统计页面采用 React Native 函数式组件开发范式,融合了企业级应用特有的进度条数据可视化、结构化列表展示、功能按钮分组等核心技术点,完全贴合电子合同统计场景的开发特性。

1. 页面结构

页面按“功能模块+视觉层级”构建了清晰的分层布局,符合企业级应用的信息展示逻辑:

  • 头部区域(Header):采用 flexDirection: 'row' + justifyContent: 'space-between' 实现标题与功能图标的左右分布,保证页面核心标识与操作入口的视觉平衡。头部同时集成了 Base64 格式的图标和 Emoji 符号,兼顾了自定义图标和轻量视觉元素的使用场景,这种混合图标方案在鸿蒙端可通过 Image 组件加载 Base64 图片、Text 组件展示 Emoji 实现等价效果。
  • 内容区域(Content):通过 ScrollView 承载可滚动内容,内部按“数据概览+列表记录+操作按钮”的逻辑拆分为三个功能区块:
    • 签署概览区块:采用进度条(View 模拟)+ 文本的组合实现数据可视化,通过动态 width 属性控制进度条长度,直观展示合同签署比例;
    • 最近签署区块:采用“左图右文+右侧操作”的经典列表布局(flexDirection: 'row'),通过 flex: 1 保证文本区域自适应,实现结构化的合同记录展示;
    • 操作按钮区块:采用等分布局(flex: 1)实现功能按钮的横向排列,通过不同背景色区分主次按钮,符合企业级应用的操作引导设计。
  • 样式分层封装:通过 StyleSheet.create 按功能模块封装样式,区分通用样式(container/content)、模块样式(section/sectionAlt)、元素样式(barRow/row),样式命名与功能强关联,保证代码的可维护性。这种样式分层方式在鸿蒙端可通过 @Styles 装饰器按模块封装样式,实现等价的样式管理逻辑。

页面采用极简的进度条设计实现合同签署状态的可视化,是企业级应用中轻量级数据展示的典型方案:

  • 进度条核心实现:通过 View 组件模拟进度条,利用 width 动态属性(如 width: '60%')控制进度长度,backgroundColor 区分不同状态(已签-绿色 #22c55e、待签-黄色 #f59e0b),borderRadius 实现圆角效果,无需引入复杂的图表库即可满足基础数据可视化需求。这种轻量级实现方式在鸿蒙端可通过 Column/Row 布局+动态宽度的 View 组件实现,核心视觉效果和数据映射逻辑完全复用。
  • 数据排版逻辑:进度条区域采用“标签+进度条+数值”的三段式布局(barRow),通过固定宽度的标签(width: 40)保证排版对齐,数值文本与进度条同色,强化视觉关联,这种排版逻辑符合企业级应用的数据展示规范,在鸿蒙端可通过固定宽度的 Text 组件+自适应的进度条+数值文本实现等价排版。

3. 交互设计:

页面聚焦核心操作的交互设计,符合企业级应用简洁、高效的交互原则:

  • 按钮交互逻辑:所有功能按钮(导出统计、分享报告)绑定统一的 onExport 回调函数,通过 Alert.alert 实现操作反馈,这种极简的交互设计避免了不必要的逻辑复杂度,在鸿蒙端可通过 promptAction.showToast/showAlert 实现等价的操作反馈。
  • 视觉交互引导:通过背景色区分主次按钮(actionBtn/actionBtnPrimary),主按钮采用高亮背景色(#ecfeff)和强调色文本(#0ea5e9),次按钮采用中性背景色(#f1f5f9)和常规文本色,通过视觉层级引导用户操作优先级,这种设计逻辑在鸿蒙端可通过条件样式渲染实现。
  • 列表交互预留:最近签署列表项预留了“下载”文本的交互入口(rowMeta),虽未实现点击逻辑,但通过蓝色文本(#0ea5e9)暗示可点击性,为后续交互扩展预留了空间,这种设计思路在鸿蒙端可通过 Button 组件替代文本实现交互能力。

4. 资源处理:

页面采用 Base64 格式存储图标资源,是 React Native 中轻量级图标集成的高效方案:

  • Base64 图标优势:避免了图片资源的网络请求或本地文件依赖,减少了应用包体积,同时保证图标加载的即时性,这种资源处理方式在鸿蒙端可直接复用,通过 Image 组件的 src 属性加载 Base64 格式的图片数据。
  • 图标样式适配:通过固定宽高(如 width: 24, height: 24)和圆角(borderRadius)实现图标的统一视觉效果,在鸿蒙端可通过 width/height/borderRadius 属性实现等价样式适配。

将该电子合同统计页面迁移至鸿蒙端,核心是“布局逻辑复用、样式属性映射、交互体验对齐”,以下从技术维度拆解关键适配点:

1. 技术栈

鸿蒙端基于 ArkTS 开发,与 React Native 的函数式组件思想和 TypeScript 语法高度兼容,核心差异集中在组件定义与渲染逻辑:

  • 组件定义迁移:React 函数式组件转换为鸿蒙的 @Entry + @Component 装饰的 struct,核心渲染逻辑迁移至 build() 方法:
    // 鸿蒙 ArkTS 组件定义
    @Entry
    @Component
    struct EContractStatsPersonal {
      // 导出操作方法
      onExport() {
        promptAction.showToast({
          message: '个人统计:已导出个人签署统计报告 PDF',
          duration: 2000
        });
      }
      
      build() {
        // Base64 图标常量定义
        const ICONS_BASE64 = {
          chart: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
          doc: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
          exportx: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
        };
        
        // 页面布局渲染
        SafeArea() {
          Column({ flex: 1, backgroundColor: '#f8fffb' }) {
            // 头部区域
            Row() {
              Text('电子合同 · 个人统计')
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .fontColor('#0f172a');
              
              Row() {
                Image(ICONS_BASE64.chart)
                  .width(24)
                  .height(24);
                Text('📊')
                  .fontSize(18)
                  .marginLeft(8);
              }
            }
            .padding(16)
            .backgroundColor('#ffffff')
            .borderBottom({ width: 1, color: '#d1fae5' })
            .justifyContent(FlexAlign.SpaceBetween)
            .alignItems(Alignment.Center);
            
            // 内容滚动区域
            Scroll() {
              Column({ padding: 16 }) {
                // 签署概览区块
                this.buildSignOverviewSection();
                
                // 最近签署区块
                this.buildRecentSignList(ICONS_BASE64);
                
                // 操作按钮区块
                this.buildActionButtons(ICONS_BASE64);
              }
            }
          }
        }
      }
      
      // 签署概览区块封装
      @Builder
      buildSignOverviewSection() {
        Column() {
          Text('签署概览')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
            .fontColor('#0f172a')
            .marginBottom(10);
          
          // 已签进度条
          Row() {
            Text('已签')
              .width(40)
              .fontSize(12)
              .fontColor('#64748b');
            Column()
              .width('60%')
              .height(12)
              .backgroundColor('#22c55e')
              .borderRadius(8)
              .marginRight(8);
            Text('24 份')
              .fontSize(12)
              .fontColor('#22c55e')
              .fontWeight(FontWeight.SemiBold);
          }
          .alignItems(Alignment.Center)
          .marginBottom(8);
          
          // 待签进度条
          Row() {
            Text('待签')
              .width(40)
              .fontSize(12)
              .fontColor('#64748b');
            Column()
              .width('30%')
              .height(12)
              .backgroundColor('#f59e0b')
              .borderRadius(8)
              .marginRight(8);
            Text('12 份')
              .fontSize(12)
              .fontColor('#22c55e')
              .fontWeight(FontWeight.SemiBold);
          }
          .alignItems(Alignment.Center);
        }
        .backgroundColor('#ffffff')
        .borderRadius(12)
        .padding(14)
        .shadow({ radius: 2, color: '#000', offsetX: 0, offsetY: 1, opacity: 0.08 });
      }
      
      // 其他 Builder 方法...
    }
    
  • 交互逻辑迁移:React 的 Alert.alert 弹窗反馈转换为鸿蒙的 promptAction.showToast,核心操作反馈逻辑完全复用,仅需调整API调用方式。
  • Base64 资源复用:Base64 格式的图标资源可直接在鸿蒙 Image 组件中使用,无需格式转换,保证图标展示效果的一致性。

2. 核心组件

React Native 原生组件与鸿蒙 ArkUI 组件存在清晰的映射关系,是企业级应用跨端迁移的核心落地环节:

React Native 组件 鸿蒙 ArkUI 组件 适配核心说明
SafeAreaView SafeArea 均用于适配刘海屏/底部安全区,属性一致
View Column/Row/Stack 鸿蒙通过布局组件替代通用容器,Flex 布局逻辑复用
Text Text 样式属性(fontSize/color等)仅命名规范差异,文本展示完全一致
TouchableOpacity Button/Text(带点击态) 鸿蒙可通过 Button 去除默认样式(backgroundColor: Color.Transparent)实现点击交互,保证操作按钮的交互一致性
Image Image 鸿蒙 Image 组件原生支持 Base64 格式图片加载,resizeMode 对应 objectFit
ScrollView Scroll 鸿蒙 Scroll 组件实现纵向滚动,核心滚动逻辑完全复用
StyleSheet 内联样式/@Styles 鸿蒙通过内联样式或 @Styles 装饰器封装样式,核心样式属性一一映射

以核心的最近签署列表项为例,React Native 实现与鸿蒙 ArkTS 实现的核心映射:

// React Native 列表项实现
<View style={styles.row}>
  <Image source={{ uri: ICONS_BASE64.doc }} style={styles.rowIcon} />
  <View style={styles.rowText}>
    <Text style={styles.rowTitle}>房屋租赁合同 · 已签</Text>
    <Text style={styles.rowSub}>2026-01-05</Text>
  </View>
  <Text style={styles.rowMeta}>下载</Text>
</View>

// 鸿蒙 ArkTS 等价实现
Row() {
  Image(ICONS_BASE64.doc)
    .width(32)
    .height(32)
    .borderRadius(8)
    .marginRight(10)
    .backgroundColor('#e0f2fe');
  
  Column() {
    Text('房屋租赁合同 · 已签')
      .fontSize(13)
      .fontWeight(FontWeight.SemiBold)
      .fontColor('#0f172a');
    Text('2026-01-05')
      .fontSize(12)
      .fontColor('#64748b')
      .marginTop(2);
  }
  .flexGrow(1);
  
  Text('下载')
    .fontSize(11)
    .fontColor('#0ea5e9');
}
.padding({ top: 10, bottom: 10 })
.borderBottom({ width: 1, color: '#f3f4f6' });

React Native 的 StyleSheet.create 封装样式的方式,在鸿蒙端可通过内联样式+@Styles 装饰器实现等价封装,核心样式属性的适配规则如下:

  • 布局属性映射
    React Native 样式属性 鸿蒙样式属性 适配示例
    flexDirection flexDirection ‘row’ → FlexDirection.Row
    justifyContent justifyContent ‘space-between’ → FlexAlign.SpaceBetween
    alignItems alignItems ‘center’ → Alignment.Center
    flex: 1 flexGrow: 1 实现区域自适应
    marginBottom marginBottom 数值直接复用
  • 视觉样式映射
    • borderRadius 完全复用,保证进度条(8px)、卡片(12px)、图标(8px)的圆角一致性;
    • backgroundColor 直接映射,企业级应用特有的绿色系(#22c55e 已签状态)、黄色系(#f59e0b 待签状态)、蓝色系(#0ea5e9 操作文本)可 100% 复用;
    • shadow 样式转换:React Native 的 shadowColor/shadowOffset/shadowOpacity/shadowRadius 转换为鸿蒙的 shadow 配置对象:
      // React Native 阴影样式
      shadowColor: '#000',
      shadowOffset: { width: 0, height: 1 },
      shadowOpacity: 0.08,
      shadowRadius: 2
      
      // 鸿蒙等价阴影样式
      .shadow({
        radius: 2,
        color: '#000',
        offsetX: 0,
        offsetY: 1,
        opacity: 0.08
      })
      
  • 文本样式映射
    • fontWeight: 'bold'fontWeight: FontWeight.Bold
    • fontWeight: '600'fontWeight: FontWeight.SemiBold
    • numberOfLinesmaxLines
    • 字体大小、颜色属性直接复用数值和色值。

电子合同统计页面作为企业级应用的核心页面,对加载性能、交互响应速度要求极高,跨端迁移需重点保证以下体验一致性:

  • 滚动性能优化:鸿蒙的 Scroll 组件默认性能优异,对于大量合同记录场景,可通过 List 组件替代 Scroll 实现虚拟化渲染,仅渲染可视区域内的列表项,提升滚动流畅度;
  • 图片加载优化:Base64 格式的图标在鸿蒙端加载无性能损耗,保证图标的即时渲染,对于网络图片场景,可通过 Image 组件的 cachePolicy 属性实现图片缓存,提升加载速度;
  • 交互响应优化:React Native 的 TouchableOpacity 点击反馈在鸿蒙端可通过 Button 组件的 stateEffect: true 实现,保证操作按钮的点击反馈一致性;对于列表项的“下载”文本,可封装为 Button 组件并去除默认样式,实现点击交互能力;
  • 企业级体验增强:鸿蒙端可利用 @ohos.fileio 模块实现统计报告的本地导出功能,补充 React Native 版本的模拟导出逻辑;利用鸿蒙的 PDF 组件实现合同文件的预览,提升企业级应用的功能完整性。

从该 React Native 电子合同统计页面的鸿蒙适配过程中,可提炼出企业级应用跨端开发的通用方法论:

采用基础布局组件(View/Column/Row)模拟的进度条、统计卡片等轻量级数据可视化方案,可完全跨端复用核心逻辑,仅需适配样式属性和组件语法,无需依赖第三方图表库。

Base64 格式的图标资源可直接在 React Native 和鸿蒙两端使用,避免了图片资源的格式转换和路径适配,保证图标展示效果的一致性,同时提升加载性能。

该 React Native 电子合同个人统计页面的实现,充分体现了企业级应用跨端开发的工程化思想:分层布局保证信息展示的结构化,轻量级数据可视化满足基础统计需求,Base64 资源方案提升加载性能,样式分层封装保证可维护性。向鸿蒙端迁移时,核心业务逻辑、布局思路、样式体系可完全复用,仅需适配组件语法、样式属性和原生 API 调用,适配成本可控制在 20%-30% 以内。


真实演示案例代码:



import React from 'react';
import { SafeAreaView, View, Text, StyleSheet, TouchableOpacity, ScrollView, Alert, Image } from 'react-native';

const ICONS_BASE64 = {
  chart: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
  doc: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
  exportx: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
};

const EContractStatsPersonal: React.FC = () => {
  const onExport = () => Alert.alert('个人统计', '已导出个人签署统计报告 PDF');

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.title}>电子合同 · 个人统计</Text>
        <View style={styles.headerIcons}>
          <Image source={{ uri: ICONS_BASE64.chart }} style={styles.headerIconImg} />
          <Text style={styles.headerEmoji}>📊</Text>
        </View>
      </View>

      <ScrollView style={styles.content}>
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>签署概览</Text>
          <View style={styles.barRow}>
            <Text style={styles.barLabel}>已签</Text>
            <View style={[styles.bar, { width: '60%' }]} />
            <Text style={styles.barMeta}>24</Text>
          </View>
          <View style={styles.barRow}>
            <Text style={styles.barLabel}>待签</Text>
            <View style={[styles.bar, { width: '30%', backgroundColor: '#f59e0b' }]} />
            <Text style={styles.barMeta}>12</Text>
          </View>
        </View>

        <View style={styles.sectionAlt}>
          <Text style={styles.sectionTitle}>最近签署</Text>
          <View style={styles.row}>
            <Image source={{ uri: ICONS_BASE64.doc }} style={styles.rowIcon} />
            <View style={styles.rowText}>
              <Text style={styles.rowTitle}>房屋租赁合同 · 已签</Text>
              <Text style={styles.rowSub}>2026-01-05</Text>
            </View>
            <Text style={styles.rowMeta}>下载</Text>
          </View>
          <View style={styles.row}>
            <Image source={{ uri: ICONS_BASE64.doc }} style={styles.rowIcon} />
            <View style={styles.rowText}>
              <Text style={styles.rowTitle}>服务协议 · 已签</Text>
              <Text style={styles.rowSub}>2026-01-03</Text>
            </View>
            <Text style={styles.rowMeta}>下载</Text>
          </View>
        </View>

        <View style={styles.actionBar}>
          <TouchableOpacity style={styles.actionBtn} onPress={onExport}>
            <Image source={{ uri: ICONS_BASE64.exportx }} style={styles.actionIcon} />
            <Text style={styles.actionText}>导出统计</Text>
          </TouchableOpacity>
          <TouchableOpacity style={[styles.actionBtn, styles.actionBtnPrimary]} onPress={onExport}>
            <Image source={{ uri: ICONS_BASE64.chart }} style={styles.actionIcon} />
            <Text style={styles.actionTextPrimary}>分享报告</Text>
          </TouchableOpacity>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#f8fffb' },
  header: { padding: 16, backgroundColor: '#ffffff', borderBottomWidth: 1, borderBottomColor: '#d1fae5', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
  title: { fontSize: 18, fontWeight: 'bold', color: '#0f172a' },
  headerIcons: { flexDirection: 'row', alignItems: 'center' },
  headerEmoji: { fontSize: 18, marginLeft: 8 },
  headerIconImg: { width: 24, height: 24 },
  content: { padding: 16 },
  section: { backgroundColor: '#ffffff', borderRadius: 12, padding: 14, shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.08, shadowRadius: 2 },
  sectionAlt: { backgroundColor: '#ecfeff', borderRadius: 12, padding: 14, marginTop: 16 },
  sectionTitle: { fontSize: 16, fontWeight: 'bold', color: '#0f172a', marginBottom: 10 },
  barRow: { flexDirection: 'row', alignItems: 'center', marginBottom: 8 },
  barLabel: { width: 40, fontSize: 12, color: '#64748b' },
  bar: { height: 12, backgroundColor: '#22c55e', borderRadius: 8, marginRight: 8 },
  barMeta: { fontSize: 12, color: '#22c55e', fontWeight: '600' },
  row: { flexDirection: 'row', alignItems: 'center', paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: '#f3f4f6' },
  rowIcon: { width: 32, height: 32, borderRadius: 8, marginRight: 10, backgroundColor: '#e0f2fe' },
  rowText: { flex: 1 },
  rowTitle: { fontSize: 13, fontWeight: '600', color: '#0f172a' },
  rowSub: { fontSize: 12, color: '#64748b', marginTop: 2 },
  rowMeta: { fontSize: 11, color: '#0ea5e9' },
  actionBar: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 18 },
  actionBtn: { flex: 1, backgroundColor: '#f1f5f9', borderRadius: 12, paddingVertical: 12, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', marginRight: 10 },
  actionBtnPrimary: { backgroundColor: '#ecfeff', marginRight: 0 },
  actionIcon: { width: 16, height: 16, marginRight: 6 },
  actionText: { fontSize: 14, color: '#334155', fontWeight: '500' },
  actionTextPrimary: { fontSize: 14, color: '#0ea5e9', fontWeight: '600' },
});

export default EContractStatsPersonal;

请添加图片描述


打包

接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

在这里插入图片描述

打包之后再将打包后的鸿蒙OpenHarmony文件拷贝到鸿蒙的DevEco-Studio工程目录去:

在这里插入图片描述

最后运行效果图如下显示:
请添加图片描述
本文剖析了一个基于React Native开发的电子合同个人统计组件,重点解读其跨平台实现方案。组件采用函数式编程和Hooks系统,模块化设计包含头部、签署概览、最近签署和操作栏四部分。通过Base64编码图标资源和Flexbox布局实现跨平台兼容性,使用StyleSheet优化样式性能。文章还探讨了该组件向鸿蒙系统迁移的注意事项,包括核心组件适配、性能优化策略等,为企业级跨平台应用开发提供了实践参考。

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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐