请添加图片描述

项目介绍

这是一个基于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. 布局切换实现

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. 动态步骤状态管理

// 步骤状态定义: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. 步骤表单集成

// 步骤表单集成器
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结构
<div id="step-indicator" class="step-indicator"></div>
  <div id="form-container">
    <form class="step-form">
    <!-- 第一步表单内容 -->
    </form>
      <form class="step-form">
      <!-- 第二步表单内容 -->
      </form>
      <!-- 更多步骤表单 -->
      </div>
  1. 初始化步骤指示器
// 步骤配置
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属性设置
const steps = [
{
title: '上传文件',
description: '上传必要的证明文件',
icon: '', // 自定义图标
color: '#4285f4' // 自定义颜色
},
// 其他步骤...
];
  • 布局切换与强制设置
// 切换为垂直布局
stepIndicator.setLayout('vertical');
// 强制设置布局,不受窗口大小影响
stepIndicator.setLayout('vertical', true);
  • 手动控制步骤状态
// 标记第二步为出错状态
stepIndicator.updateStepState(1, STEP_STATES.ERROR);
// 跳转到指定步骤
stepIndicator.goToStep(2);

运行方法

  1. 安装依赖
npm install
  1. 启动应用
npm start
  1. 运行示例
npm run demo

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

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应用代码按以下目录结构放置:
在这里插入图片描述

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动画效果,减少重绘频率