Electron for鸿蒙PC封装的步骤进度指示器组件

项目介绍

这是一个基于Electron for鸿蒙PC封装步骤进度指示器组件,专为多步骤流程场景设计,如表单提交、流程向导、安装步骤等。该组件提供直观的进度可视化功能,支持灵活的布局配置和动态状态管理,帮助用户清晰了解当前所处流程位置及整体进度。

功能特点

  • 布局灵活:支持水平和垂直两种布局模式,适配不同场景的空间需求
  • 状态可视化:提供未开始、进行中、已完成、出错四种状态的视觉区分
  • 表单集成:与步骤表单深度集成,支持步骤切换时的表单验证
  • 动画效果:状态切换和布局转换时的平滑过渡动画
  • 自定义配置:支持步骤标题、描述、图标等内容的自定义
  • 响应式设计:在不同屏幕尺寸下自动调整布局,移动设备优先采用垂直布局
  • 交互反馈:提供点击、拖拽等交互方式的视觉反馈
  • 主题适配:支持浅色/深色主题,可自定义颜色和尺寸参数

技术实现

主进程(main.js)

主进程负责应用窗口管理和步骤数据的持久化存储,通过Electron的IPC机制提供步骤状态的保存与恢复功能,确保流程中断后可继续。

预加载脚本(preload.js)

使用contextBridge暴露步骤进度指示器的核心API,包括步骤状态管理、布局切换、进度保存等功能,确保渲染进程安全访问系统资源。

渲染进程(renderer.js)

实现组件的核心交互逻辑:

  • 布局引擎:处理水平/垂直布局的切换与计算
  • 状态管理器:维护步骤的状态变化与历史记录
  • 表单集成器:处理步骤与表单的联动及验证逻辑
  • 动画控制器:管理状态切换和布局转换的动画效果
  • 响应式处理器:根据屏幕尺寸自动调整布局模式

样式实现(style.css)

通过CSS变量实现主题定制,使用Flexbox布局实现水平/垂直两种排列方式,为不同状态定义专属样式,通过CSS过渡实现平滑的状态切换效果。

代码结构

  • main.js - Electron主进程代码,管理窗口与数据持久化
  • preload.js - 预加载脚本,安全暴露核心API
  • index.html - 步骤指示器组件界面结构
  • style.css - 样式定义,包含布局与状态样式
  • renderer.js - 渲染进程逻辑,处理核心功能实现
  • stepUtils.js - 工具类,提供步骤计算与状态转换方法
  • stepConfig.js - 配置管理,处理布局与样式配置

核心代码示例

1. 布局切换实现

javascript 复制代码
class StepIndicator {
  constructor(container, options) {
    this.container = container;
    this.steps = options.steps || [];
    this.currentStep = options.initialStep || 0;
    this.layout = options.layout || 'horizontal'; // 默认为水平布局
    
    // 初始化布局
    this.initLayout();
    // 响应窗口大小变化
    window.addEventListener('resize', this.handleResize.bind(this));
  }
  
  // 初始化布局
  initLayout() {
    this.container.className = `step-indicator ${this.layout}`;
    this.renderSteps();
  }
  
  // 切换布局
  setLayout(layout) {
    if (layout !== 'horizontal' && layout !== 'vertical') return;
    this.layout = layout;
    this.container.classList.remove('horizontal', 'vertical');
    this.container.classList.add(layout);
    this.renderSteps();
  }
  
  // 响应式布局处理
  handleResize() {
    if (window.innerWidth < 768 && this.layout === 'horizontal') {
      this.setLayout('vertical'); // 小屏幕自动切换为垂直布局
    } else if (window.innerWidth >= 768 && this.layout === 'vertical' && 
              !this.userForcedLayout) {
      this.setLayout('horizontal'); // 大屏幕自动切换为水平布局
    }
  }
  
  // 渲染步骤
  renderSteps() {
    this.container.innerHTML = this.steps.map((step, index) => this.renderStep(step, index)).join('');
    this.updateConnectors(); // 更新步骤间的连接线
  }
}

2. 动态步骤状态管理

javascript 复制代码
// 步骤状态定义:0-未开始,1-进行中,2-已完成,3-出错
const STEP_STATES = {
  PENDING: 0,
  ACTIVE: 1,
  COMPLETED: 2,
  ERROR: 3
};

// 更新步骤状态
updateStepState(index, state) {
  if (index < 0 || index >= this.steps.length) return;
  
  // 更新内部状态
  this.steps[index].state = state;
  
  // 更新UI
  const stepElement = this.container.querySelector(`.step-item[data-index="${index}"]`);
  if (!stepElement) return;
  
  // 移除所有状态类
  Object.values(STEP_STATES).forEach(s => {
    stepElement.classList.remove(`state-${s}`);
  });
  // 添加当前状态类
  stepElement.classList.add(`state-${state}`);
  
  // 更新图标
  const iconElement = stepElement.querySelector('.step-icon');
  switch(state) {
    case STEP_STATES.COMPLETED:
      iconElement.innerHTML = '✓'; // 完成图标
      break;
    case STEP_STATES.ERROR:
      iconElement.innerHTML = '!'; // 错误图标
      break;
    case STEP_STATES.ACTIVE:
      iconElement.innerHTML = index + 1; // 当前步骤显示序号
      break;
    default:
      iconElement.innerHTML = index + 1; // 未开始显示序号
  }
  
  // 触发状态变化事件
  this.emit('stepStateChange', { index, state });
}

// 前进到下一步
nextStep() {
  if (this.currentStep >= this.steps.length - 1) return;
  
  // 标记当前步骤为已完成
  this.updateStepState(this.currentStep, STEP_STATES.COMPLETED);
  // 前进到下一步
  this.currentStep++;
  // 标记下一步为进行中
  this.updateStepState(this.currentStep, STEP_STATES.ACTIVE);
  
  this.emit('stepChange', { currentStep: this.currentStep });
}

// 返回到上一步
prevStep() {
  if (this.currentStep <= 0) return;
  
  // 标记当前步骤为未开始
  this.updateStepState(this.currentStep, STEP_STATES.PENDING);
  // 返回到上一步
  this.currentStep--;
  // 标记上一步为进行中
  this.updateStepState(this.currentStep, STEP_STATES.ACTIVE);
  
  this.emit('stepChange', { currentStep: this.currentStep });
}

3. 步骤表单集成

javascript 复制代码
// 步骤表单集成器
class StepFormIntegrator {
  constructor(stepIndicator, formContainer) {
    this.stepIndicator = stepIndicator;
    this.formContainer = formContainer;
    this.forms = Array.from(formContainer.querySelectorAll('.step-form'));
    
    // 初始化表单状态
    this.initForms();
    
    // 监听步骤变化
    this.stepIndicator.on('stepChange', (e) => this.showStepForm(e.currentStep));
  }
  
  // 初始化表单
  initForms() {
    // 隐藏所有表单,只显示当前步骤表单
    this.forms.forEach((form, index) => {
      form.classList.toggle('active', index === this.stepIndicator.currentStep);
      // 绑定表单提交事件
      form.addEventListener('submit', (e) => {
        e.preventDefault();
        this.handleFormSubmit(index);
      });
    });
  }
  
  // 显示指定步骤的表单
  showStepForm(stepIndex) {
    this.forms.forEach((form, index) => {
      form.classList.toggle('active', index === stepIndex);
    });
  }
  
  // 处理表单提交
  handleFormSubmit(stepIndex) {
    const form = this.forms[stepIndex];
    // 验证当前步骤表单
    if (this.validateForm(form)) {
      // 表单验证通过,保存表单数据
      this.saveFormData(stepIndex, this.getFormData(form));
      // 前进到下一步
      this.stepIndicator.nextStep();
    } else {
      // 表单验证失败,标记步骤为错误状态
      this.stepIndicator.updateStepState(stepIndex, STEP_STATES.ERROR);
      // 显示错误提示
      this.showFormErrors(form);
    }
  }
  
  // 表单验证
  validateForm(form) {
    const inputs = form.querySelectorAll('[required]');
    let isValid = true;
    
    inputs.forEach(input => {
      if (!input.checkValidity()) {
        input.classList.add('invalid');
        isValid = false;
      } else {
        input.classList.remove('invalid');
      }
    });
    
    return isValid;
  }
  
  // 获取表单数据
  getFormData(form) {
    const formData = new FormData(form);
    const data = {};
    formData.forEach((value, key) => {
      data[key] = value;
    });
    return data;
  }
  
  // 保存表单数据
  saveFormData(stepIndex, data) {
    // 通过IPC保存到主进程或本地存储
    window.electron.saveStepData(stepIndex, data);
  }
}

如何使用

基本使用

  1. 定义步骤配置和HTML结构
html 复制代码
<div id="step-indicator" class="step-indicator"></div>

<div id="form-container">
  <form class="step-form">
    <!-- 第一步表单内容 -->
  </form>
  <form class="step-form">
    <!-- 第二步表单内容 -->
  </form>
  <!-- 更多步骤表单 -->
</div>
  1. 初始化步骤指示器
javascript 复制代码
// 步骤配置
const steps = [
  { title: '基本信息', description: '填写个人基本信息' },
  { title: '选择方案', description: '选择适合您的方案' },
  { title: '确认提交', description: '确认信息并提交' }
];

// 初始化步骤指示器
const stepIndicator = new StepIndicator('#step-indicator', {
  steps: steps,
  initialStep: 0,
  layout: 'horizontal'
});

// 集成表单
const formIntegrator = new StepFormIntegrator(stepIndicator, '#form-container');

高级配置

  • 自定义步骤样式 :通过data属性设置
javascript 复制代码
const steps = [
  { 
    title: '上传文件', 
    description: '上传必要的证明文件',
    icon: '📂', // 自定义图标
    color: '#4285f4' // 自定义颜色
  },
  // 其他步骤...
];
  • 布局切换与强制设置
javascript 复制代码
// 切换为垂直布局
stepIndicator.setLayout('vertical');

// 强制设置布局,不受窗口大小影响
stepIndicator.setLayout('vertical', true);
  • 手动控制步骤状态
javascript 复制代码
// 标记第二步为出错状态
stepIndicator.updateStepState(1, STEP_STATES.ERROR);

// 跳转到指定步骤
stepIndicator.goToStep(2);

运行方法

  1. 安装依赖
bash 复制代码
npm install
  1. 启动应用
bash 复制代码
npm start
  1. 运行示例
bash 复制代码
npm run demo

鸿蒙适配后结构(需整合到 Electron 鸿蒙项目模板中):

plaintext 复制代码
ohos_hap/
├── electron/
│   ├── libs/
│   │   └── arm64-v8a/  # 鸿蒙核心库文件
│   │       ├── libelectron.so
│   │       ├── libadapter.so
│   │       ├── libffmpeg.so
│   │       └── libc++_shared.so
├── web_engine/
│   └── src/
│       └── main/
│           └── resources/
│               └── resfile/
│                   └── resources/
│                       └── app/  # 放置electron应用代码
│                           ├── main.js
│                           ├── package.json
│                           └── src/
└── module.json5        # 鸿蒙应用配置文件

鸿蒙PC适配改造指南

1. 环境准备

  • 系统要求:Windows 10/11、8GB RAM以上、20GB可用空间

  • 工具安装

    DevEco Studio 5.0+(安装鸿蒙SDK API 20+)

  • Node.js 18.x+

2. 获取Electron鸿蒙编译产物

  1. 登录Electron 鸿蒙官方仓库

  2. 下载Electron 34+版本的Release包(.zip格式)

  3. 解压到项目目录,确认electron/libs/arm64-v8a/下包含核心.so库

3. 部署应用代码

将Electron应用代码按以下目录结构放置:

plaintext 复制代码
web_engine/src/main/resources/resfile/resources/app/
├── main.js
├── package.json
└── src/
    ├── index.html
    ├── preload.js
    ├── renderer.js
    └── style.css

4. 配置与运行

  1. 打开项目:在DevEco Studio中打开ohos_hap目录

  2. 配置签名

    进入File → Project Structure → Signing Configs

  3. 自动生成调试签名或导入已有签名

  4. 连接设备

    启用鸿蒙设备开发者模式和USB调试

  5. 通过USB Type-C连接电脑

  6. 编译运行:点击Run按钮或按Shift+F10

5. 验证检查项

  • ✅ 应用窗口正常显示

  • ✅ 窗口大小可调整,响应式布局生效

  • ✅ 控制台无"SysCap不匹配"或"找不到.so文件"错误

  • ✅ 动画效果正常播放

跨平台兼容性

平台 适配策略 特殊处理
Windows 标准Electron运行 无特殊配置
macOS 标准Electron运行 保留dock图标激活逻辑
Linux 标准Electron运行 确保系统依赖库完整
鸿蒙PC 通过Electron鸿蒙适配层 禁用硬件加速,使用特定目录结构

鸿蒙开发调试技巧

1. 日志查看

在DevEco Studio的Log面板中过滤"Electron"关键词,查看应用运行日志和错误信息。

2. 常见问题解决

  • "SysCap不匹配"错误:检查module.json5中的reqSysCapabilities,只保留必要系统能力

  • "找不到.so文件"错误:确认arm64-v8a目录下四个核心库文件完整

  • 窗口不显示:在main.js中添加app.disableHardwareAcceleration()

  • 动画卡顿:简化CSS动画效果,减少重绘频率

相关推荐
赵财猫._.2 小时前
【Flutter x 鸿蒙】第八篇:打包发布、应用上架与运营监控
flutter·华为·harmonyos
晚霞的不甘2 小时前
[鸿蒙2025领航者闯关]: Flutter + OpenHarmony 安全开发实战:从数据加密到权限管控的全链路防护
安全·flutter·harmonyos
灰灰勇闯IT2 小时前
[鸿蒙2025领航者闯关] 鸿蒙6.0星盾安全架构实战:打造金融级支付应用的安全防护
安全·harmonyos·安全架构
禁默2 小时前
[鸿蒙2025领航者闯关] 鸿蒙 6 特性实战闯关:金融支付应用的安全升级之路
安全·金融·harmonyos·鸿蒙2025领航者闯关·鸿蒙6实战
国服第二切图仔2 小时前
基于Electron for 鸿蒙开发的现代化颜色选择器
microsoft·electron·harmonyos
PegasusYu2 小时前
Electron使用WebAssembly实现CRC-16 X25校验
electron·nodejs·wasm·webassembly·crc16·crc-16·x25
国服第二切图仔2 小时前
基于Electron for 鸿蒙PC的高性能表格组件封装
javascript·electron·harmonyos·鸿蒙pc
wshzd2 小时前
LLM之Agent(三十九)|AI Agents(八):构建Multi-Agent系统
人工智能·microsoft
2401_860494702 小时前
在React Native鸿蒙跨平台开发中实现一个桶排序算法,如何使用任何排序算法对每个桶中的元素进行排序,再将所有桶中的元素合并成一个有序数组
javascript·react native·react.js·ecmascript·排序算法·harmonyos