欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net


项目效果

本文实现的是一个基于 @pura/harmony-utils 的 Base64 文本编码解码工具页面。用户可以在页面中输入普通文本,点击“编码”按钮后,应用会将文本转换为 Base64 字符串;点击“解码”按钮后,页面会将 Base64 字符串还原为原始文本。

最终运行效果如下:
在这里插入图片描述

页面主要包含以下内容:

  • 顶部标题:Base64 编码工具;
  • 原始文本输入区域;
  • Base64 编码结果展示;
  • 解码结果展示;
  • 编码按钮;
  • 解码按钮;
  • 填充示例按钮;
  • 清空按钮;
  • 操作状态提示;
  • 页面整体采用卡片式布局。

这个页面可以作为文本编码、接口数据处理、配置内容转换、调试工具、轻量数据交换等项目的基础版本。


前言

在应用开发中,Base64 编码是一种非常常见的数据转换方式。它可以把普通文本或二进制数据转换成可传输的字符串形式,常用于接口传参、图片数据转换、文件内容传输、配置保存等场景。

Base64 本身不是加密算法,它只是编码方式。也就是说,把内容转成 Base64 并不代表安全,只是换了一种表现形式。不要把 Base64 当密码保险箱,不然程序员和安全人员都会沉默。

本篇文章选择使用 OpenHarmony 三方工具库 @pura/harmony-utils 来实现 Base64 文本编码和解码功能。该工具库中封装了常用的字符串处理、Base64、加密、日期、集合等工具方法,适合在日常开发中快速完成一些基础功能。

本篇文章以“Base64 文本编码解码工具”为场景,使用 StrUtil.strToBase64() 将普通文本转换为 Base64 字符串,再使用 StrUtil.base64ToStr() 将 Base64 字符串还原为普通文本,并结合 ArkUI 构建一个完整的工具页面。


一、项目目标

本次实践主要实现以下目标:

  • 在 OpenHarmony 项目中安装 @pura/harmony-utils 三方库;
  • 在 ArkTS 页面中引入并使用 StrUtil
  • 使用 TextArea 接收用户输入的普通文本;
  • 将普通文本转换为 Base64 字符串;
  • 将 Base64 字符串解码为普通文本;
  • 展示编码前后的文本长度;
  • 使用 ArkUI 构建工具类页面;
  • 实现填充示例、清空内容和状态提示;
  • 在 OpenHarmony 模拟器中完成运行验证。

二、技术栈

类型 内容
实战方向 Flutter for OpenHarmony 三方库实战
实现平台 OpenHarmony
开发语言 ArkTS
三方库 @pura/harmony-utils
使用工具类 StrUtil
功能场景 Base64 编码 / Base64 解码
UI 框架 ArkUI
开发工具 DevEco Studio
运行环境 OpenHarmony 模拟器

三、为什么选择 harmony-utils

在 OpenHarmony 应用开发中,很多基础功能并不复杂,但如果每次都手写,会让页面代码变得比较散。例如:

  • 字符串处理;
  • Base64 编码;
  • 日期格式化;
  • 随机数生成;
  • JSON 处理;
  • 集合处理;
  • 加密解密;
  • 文件或设备相关工具方法。

@pura/harmony-utils 提供了比较丰富的工具类,可以减少重复代码,让开发者更专注于页面功能本身。

在本项目中,@pura/harmony-utils 主要用于:

  • 将普通字符串转换为 Base64;
  • 将 Base64 字符串还原为普通文本;
  • 简化字符串编码解码逻辑;
  • 构建一个本地文本处理工具页面。

通过这个项目,可以比较直观地理解工具类三方库在 OpenHarmony 项目中的使用方式。


四、安装 harmony-utils 三方库

在项目根目录打开终端,执行以下命令:

ohpm install @pura/harmony-utils

或者使用简写命令:

ohpm i @pura/harmony-utils

安装完成后,可以检查项目中是否出现以下内容:

oh_modules
oh-package-lock.json5
oh-package.json5

如果依赖安装成功,就可以在 ArkTS 页面中引入:

import { StrUtil } from '@pura/harmony-utils';

本项目主要使用 StrUtil 中的 Base64 字符串转换方法。


五、项目结构

本次主要修改页面文件即可:

entry
 └── src
     └── main
         └── ets
             └── pages
                 └── Index.ets

如果你的项目中原本已经有 Index.ets,可以直接替换页面内容。

文件说明:

文件 作用
Index.ets 页面展示、文本输入、Base64 编码解码和结果渲染

本项目不需要请求远程接口,因此不需要配置网络权限。页面中的所有操作都在本地完成。


六、页面状态设计

页面中主要使用以下状态变量:

@State inputText: string = '';
@State base64Text: string = '';
@State decodedText: string = '';
@State resultText: string = '请输入文本后进行编码';
@State resultColor: string = '#999999';
@State inputLengthText: string = '0';
@State base64LengthText: string = '0';

字段说明如下:

状态变量 作用
inputText 保存用户输入的原始文本
base64Text 保存 Base64 编码结果
decodedText 保存解码后的文本
resultText 保存操作结果提示
resultColor 控制提示文字颜色
inputLengthText 原始文本长度
base64LengthText Base64 文本长度

七、核心功能设计

本项目的核心流程如下:

  1. 用户输入普通文本;
  2. 点击“编码”按钮;
  3. 使用 StrUtil.strToBase64() 将文本转成 Base64;
  4. 页面展示 Base64 编码结果;
  5. 点击“解码”按钮;
  6. 使用 StrUtil.base64ToStr() 将 Base64 还原成普通文本;
  7. 页面展示解码结果。

核心编码代码如下:

const encoded = StrUtil.strToBase64(text);

核心解码代码如下:

const decoded = StrUtil.base64ToStr(this.base64Text);

这样就可以完成文本和 Base64 之间的双向转换。


八、Index.ets 完整代码

打开文件:

entry/src/main/ets/pages/Index.ets

完整代码如下:

import { StrUtil } from '@pura/harmony-utils';

@Entry
@Component
struct Index {
  @State inputText: string = '';
  @State base64Text: string = '';
  @State decodedText: string = '';
  @State resultText: string = '请输入文本后进行编码';
  @State resultColor: string = '#999999';
  @State inputLengthText: string = '0';
  @State base64LengthText: string = '0';

  aboutToAppear(): void {
    this.fillSample();
    this.encodeText();
  }

  fillSample(): void {
    this.inputText = 'OpenHarmony 是面向全场景的开源操作系统。本文使用 harmony-utils 实现 Base64 文本编码和解码工具。';
    this.base64Text = '';
    this.decodedText = '';
    this.resultText = '已填充示例文本,可以点击编码进行测试';
    this.resultColor = '#0A59F7';
    this.updateLengthInfo();
  }

  clearAll(): void {
    this.inputText = '';
    this.base64Text = '';
    this.decodedText = '';
    this.resultText = '请输入文本后进行编码';
    this.resultColor = '#999999';
    this.inputLengthText = '0';
    this.base64LengthText = '0';
  }

  updateLengthInfo(): void {
    this.inputLengthText = this.inputText.length.toString();
    this.base64LengthText = this.base64Text.length.toString();
  }

  encodeText(): void {
    const text = this.inputText.trim();

    if (text === '') {
      this.base64Text = '';
      this.decodedText = '';
      this.resultText = '原始文本不能为空';
      this.resultColor = '#E84026';
      this.updateLengthInfo();
      return;
    }

    try {
      const encoded = StrUtil.strToBase64(text);
      this.base64Text = encoded;
      this.decodedText = '';
      this.resultText = 'Base64 编码成功';
      this.resultColor = '#00A870';
      this.updateLengthInfo();
    } catch (error) {
      this.resultText = '编码失败,请检查输入内容';
      this.resultColor = '#E84026';
    }
  }

  decodeText(): void {
    const text = this.base64Text.trim();

    if (text === '') {
      this.decodedText = '';
      this.resultText = '当前没有可解码的 Base64 内容';
      this.resultColor = '#E84026';
      return;
    }

    try {
      const decoded = StrUtil.base64ToStr(text);
      this.decodedText = decoded;
      this.resultText = 'Base64 解码成功';
      this.resultColor = '#00A870';
    } catch (error) {
      this.decodedText = '';
      this.resultText = '解码失败,请确认内容是否为有效 Base64 字符串';
      this.resultColor = '#E84026';
    }
  }

  build() {
    Scroll() {
      Column() {
        Column() {
          Text('Base64 编码工具')
            .fontSize(30)
            .fontWeight(FontWeight.Bold)
            .fontColor('#182431')

          Text('基于 harmony-utils 的文本编码解码页面')
            .fontSize(14)
            .fontColor('#666666')
            .margin({ top: 8 })
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)
        .padding({
          left: 16,
          right: 16,
          top: 28,
          bottom: 12
        })

        Column() {
          Text('原始文本')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
            .fontColor('#182431')
            .margin({ bottom: 12 })

          TextArea({
            placeholder: '请输入需要编码的文本内容',
            text: this.inputText
          })
            .height(140)
            .fontSize(15)
            .backgroundColor('#FFFFFF')
            .borderRadius(12)
            .padding({
              left: 14,
              right: 14,
              top: 10,
              bottom: 10
            })
            .onChange((value: string) => {
              this.inputText = value;
              this.inputLengthText = value.length.toString();
            })

          Row() {
            Button('编码')
              .fontSize(15)
              .height(42)
              .layoutWeight(1)
              .onClick(() => {
                this.encodeText();
              })

            Button('解码')
              .fontSize(15)
              .height(42)
              .layoutWeight(1)
              .margin({ left: 10 })
              .onClick(() => {
                this.decodeText();
              })

            Button('清空')
              .fontSize(15)
              .height(42)
              .layoutWeight(1)
              .margin({ left: 10 })
              .onClick(() => {
                this.clearAll();
              })
          }
          .width('100%')
          .margin({ top: 16 })

          Button('填充示例')
            .width('100%')
            .height(42)
            .fontSize(15)
            .margin({ top: 10 })
            .onClick(() => {
              this.fillSample();
              this.encodeText();
            })
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)
        .padding(16)
        .margin({
          left: 16,
          right: 16
        })
        .backgroundColor('#F7F8FA')
        .borderRadius(18)

        Column() {
          Text('长度统计')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
            .fontColor('#182431')
            .margin({ bottom: 12 })

          Row() {
            Column() {
              Text(this.inputLengthText)
                .fontSize(28)
                .fontWeight(FontWeight.Bold)
                .fontColor('#0A59F7')

              Text('原始文本长度')
                .fontSize(13)
                .fontColor('#666666')
                .margin({ top: 4 })
            }
            .layoutWeight(1)
            .alignItems(HorizontalAlign.Center)

            Column() {
              Text(this.base64LengthText)
                .fontSize(28)
                .fontWeight(FontWeight.Bold)
                .fontColor('#0A59F7')

              Text('编码后长度')
                .fontSize(13)
                .fontColor('#666666')
                .margin({ top: 4 })
            }
            .layoutWeight(1)
            .alignItems(HorizontalAlign.Center)
          }
          .width('100%')
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)
        .padding(16)
        .margin({
          left: 16,
          right: 16,
          top: 16
        })
        .backgroundColor('#F7F8FA')
        .borderRadius(18)

        Column() {
          Text('Base64 编码结果')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
            .fontColor('#182431')
            .margin({ bottom: 12 })

          if (this.base64Text === '') {
            Text('编码结果会显示在这里')
              .fontSize(15)
              .fontColor('#999999')
              .lineHeight(24)
          } else {
            Text(this.base64Text)
              .fontSize(14)
              .fontColor('#333333')
              .lineHeight(24)
          }
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)
        .padding(16)
        .margin({
          left: 16,
          right: 16,
          top: 16
        })
        .backgroundColor('#F7F8FA')
        .borderRadius(18)

        Column() {
          Text('解码结果')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
            .fontColor('#182431')
            .margin({ bottom: 12 })

          if (this.decodedText === '') {
            Text('解码后的文本会显示在这里')
              .fontSize(15)
              .fontColor('#999999')
              .lineHeight(24)
          } else {
            Text(this.decodedText)
              .fontSize(15)
              .fontColor('#333333')
              .lineHeight(26)
          }
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)
        .padding(16)
        .margin({
          left: 16,
          right: 16,
          top: 16
        })
        .backgroundColor('#F7F8FA')
        .borderRadius(18)

        Column() {
          Text('操作结果')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
            .fontColor('#182431')
            .margin({ bottom: 12 })

          Text(this.resultText)
            .fontSize(15)
            .fontColor(this.resultColor)
            .lineHeight(24)
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)
        .padding(16)
        .margin({
          left: 16,
          right: 16,
          top: 16,
          bottom: 24
        })
        .backgroundColor('#F7F8FA')
        .borderRadius(18)
      }
      .width('100%')
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}

九、代码实现说明

1. 引入 harmony-utils

页面顶部引入三方库中的 StrUtil

import { StrUtil } from '@pura/harmony-utils';

本项目主要使用 StrUtil 中的两个方法:

StrUtil.strToBase64()
StrUtil.base64ToStr()

其中:

方法 作用
strToBase64 将普通字符串转换为 Base64 字符串
base64ToStr 将 Base64 字符串还原为普通字符串

2. Base64 编码

编码功能写在 encodeText() 方法中:

const encoded = StrUtil.strToBase64(text);
this.base64Text = encoded;

当用户点击“编码”按钮后,页面会读取输入框中的原始文本,并将其转换为 Base64 字符串。

如果输入内容为空,页面会提示:

原始文本不能为空

这样可以避免空内容继续参与编码。


3. Base64 解码

解码功能写在 decodeText() 方法中:

const decoded = StrUtil.base64ToStr(text);
this.decodedText = decoded;

当用户点击“解码”按钮后,页面会将当前 Base64 编码结果还原为普通文本。

如果当前没有 Base64 内容,页面会提示:

当前没有可解码的 Base64 内容

4. 统计文本长度

页面中提供了简单的长度统计:

this.inputLengthText = this.inputText.length.toString();
this.base64LengthText = this.base64Text.length.toString();

这样可以直观看到编码前后文本长度的变化。

需要注意的是,Base64 编码后通常会变长,这是正常现象。它的重点不是压缩,而是把数据转成更适合传输和保存的文本形式。拿它当压缩工具,就像拿雨伞炒菜,工具没错,是人类想法太奔放。


5. 填充示例和清空功能

为了方便测试,页面提供了“填充示例”和“清空”按钮。

填充示例:

fillSample(): void {
  this.inputText = 'OpenHarmony 是面向全场景的开源操作系统。';
}

清空内容:

clearAll(): void {
  this.inputText = '';
  this.base64Text = '';
  this.decodedText = '';
}

这样测试时不需要反复手动输入内容。


十、运行效果说明

完成代码后,点击 DevEco Studio 中的运行按钮,将应用运行到 OpenHarmony 模拟器中。

运行成功后,页面顶部显示:

Base64 编码工具

页面会自动填充一段示例文本,并生成对应的 Base64 编码结果。

点击“编码”按钮后,页面会展示:

  • 原始文本长度;
  • Base64 编码后长度;
  • Base64 编码结果;
  • 操作成功提示。

点击“解码”按钮后,页面会将 Base64 字符串还原为普通文本,并展示在“解码结果”区域中。

点击“清空”按钮后,页面会清除所有输入和结果。


十一、开发中遇到的问题

1. 找不到 @pura/harmony-utils 模块

如果代码中出现找不到模块的问题,可以先检查是否已经执行安装命令:

ohpm install @pura/harmony-utils

同时检查项目中是否存在:

oh_modules
oh-package-lock.json5

如果依赖没有正确安装,可以重新执行安装命令。


2. import 导入报错

如果下面代码导入时报错:

import { StrUtil } from '@pura/harmony-utils';

可以先确认 oh-package.json5 中是否已经正确写入依赖,并尝试重新同步项目或重启 DevEco Studio。

DevEco Studio 有时候像一只固执的猫,依赖明明装了,它偏要重启后才承认。


3. Base64 编码后内容变长

这是正常现象。Base64 的作用不是压缩,而是编码。

例如普通文本经过 Base64 转换后,长度通常会增加。它适合解决数据传输和文本化保存问题,不适合减少体积。

如果目标是压缩文本,应该使用类似 pako 这样的压缩库,而不是 Base64。


4. 解码失败

如果解码失败,可以检查以下内容:

  • Base64 字符串是否为空;
  • Base64 内容是否完整;
  • 是否手动修改过编码结果;
  • 是否输入了普通文本却点击了解码;
  • 字符串中是否包含非法字符。

本项目中通过 try catch 做了简单异常处理:

try {
  const decoded = StrUtil.base64ToStr(text);
} catch (error) {
  this.resultText = '解码失败,请确认内容是否为有效 Base64 字符串';
}

这样可以避免页面直接异常中断。


5. 中文是否可以编码

可以。本项目示例中使用的就是中文文本。

编码时:

StrUtil.strToBase64(text)

解码时:

StrUtil.base64ToStr(text)

可以正常完成中文字符串和 Base64 字符串之间的转换。


十二、总结

本篇完成了一个基于 @pura/harmony-utils 的 Base64 文本编码解码工具页面。项目通过 StrUtil.strToBase64() 将普通文本转换为 Base64 字符串,再通过 StrUtil.base64ToStr() 将 Base64 字符串还原为普通文本,并使用 ArkUI 展示处理结果。

通过本次实践,我主要完成了以下内容:

  • 安装并使用 @pura/harmony-utils 三方库;
  • 在 ArkTS 页面中引入 StrUtil
  • 使用 TextArea 接收用户输入文本;
  • 使用 strToBase64() 实现文本编码;
  • 使用 base64ToStr() 实现文本解码;
  • 展示编码前后的文本长度;
  • 使用 ArkUI 构建卡片式工具页面;
  • 实现填充示例、清空内容和状态提示;
  • 在模拟器中完成运行验证。

虽然这个项目只是一个基础 Base64 工具页面,但它已经包含了工具类应用中常见的输入、转换、结果展示和异常提示流程。

后续可以继续扩展为一个更完整的编码工具,例如:

  • 添加 URL 编码解码;
  • 添加 MD5 摘要生成;
  • 添加 SHA 加密摘要;
  • 添加 JSON 格式化;
  • 添加复制结果功能;
  • 添加历史记录保存;
  • 添加文件内容转 Base64;
  • 添加图片转 Base64。

整体来看,@pura/harmony-utils 可以帮助开发者更方便地完成常见工具函数调用。通过这个项目,可以更清楚地理解 OpenHarmony 中三方工具库接入、字符串处理和 ArkUI 页面展示之间的关系。

Logo

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

更多推荐