# OH_study **Repository Path**: zlaxx/oh_study ## Basic Information - **Project Name**: OH_study - **Description**: 鸿蒙最佳实践学习 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-06-24 - **Last Updated**: 2025-07-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # HarmonyOS 自定义弹窗组件 一个简洁易用、完全符合 ArkTS 规范的 HarmonyOS 弹窗封装组件,提供多种预设样式和完全自定义的弹窗功能。 ## ✨ 特性 - 🎨 **5种预设样式**:信息、成功、警告、错误、确认 - 🛠️ **完全自定义**:支持颜色、尺寸、文本等全方位定制 - 📱 **响应式设计**:适配不同屏幕尺寸 - 🔧 **简单易用**:组件内部集成,一行代码即可显示弹窗 - ✅ **符合规范**:完全遵循 HarmonyOS ArkTS 开发规范 - 🎯 **TypeScript 支持**:完整的类型定义和智能提示 - 🔒 **稳定可靠**:解决了组件上下文问题,确保弹窗正常显示 ## 📦 文件结构 ``` oh_study/ ├── entry/src/main/ets/ │ ├── utils/ │ │ └── MyDialog.ets # 弹窗核心组件 │ └── component/ │ └── EncapsulationDemo.ets # 完整使用案例 └── README.md # 本说明文档 ``` ## 🚀 快速开始 ### 1. 复制文件 将 `entry/src/main/ets/utils/MyDialog.ets` 复制到你的项目中。 ### 2. 基础用法 ```typescript import { SimpleDialog, DialogConfig, DialogType, DialogHelper } from "../utils/MyDialog"; @Component export struct MyPage { // 弹窗控制器 private dialogController: CustomDialogController = new CustomDialogController({ builder: SimpleDialog({}), alignment: DialogAlignment.Center, customStyle: true }); // 显示弹窗的方法 private showInfo(title: string, message: string): void { this.dialogController = new CustomDialogController({ builder: SimpleDialog({ title: title, message: message, confirmText: '知道了', titleColor: '#2196F3', confirmButtonColor: '#2196F3' }), alignment: DialogAlignment.Center, customStyle: true }); this.dialogController.open(); } build() { Column() { Button('显示弹窗') .onClick(() => this.showInfo('提示', '这是一条重要信息')); } } } ``` ## 📚 完整实现方案 我们的最终实现采用了**组件内部集成**的方案,解决了组件上下文访问问题。 ### 核心组件 #### 1. SimpleDialog - 弹窗UI组件 ```typescript @CustomDialog export struct SimpleDialog { controller: CustomDialogController; // 配置参数 title: string = ''; message: string = ''; confirmText: string = '确定'; cancelText: string = '取消'; showCancel: boolean = false; // 回调函数 onConfirm?: () => void; onCancel?: () => void; // 样式配置 titleColor: ResourceColor = '#333333'; messageColor: ResourceColor = '#666666'; confirmButtonColor: ResourceColor = '#007AFF'; cancelButtonColor: ResourceColor = '#F5F5F5'; dialogWidth: Length = 300; build() { // UI实现... } } ``` #### 2. DialogConfig - 配置接口 ```typescript export interface DialogConfig { title?: string; message?: string; confirmText?: string; cancelText?: string; showCancel?: boolean; onConfirm?: () => void; onCancel?: () => void; // 样式配置 titleColor?: ResourceColor; messageColor?: ResourceColor; confirmButtonColor?: ResourceColor; cancelButtonColor?: ResourceColor; dialogWidth?: Length; maskColor?: ResourceColor; } ``` #### 3. DialogHelper - 工具类 ```typescript export class DialogHelper { static createConfig(type: DialogType, title: string, message: string): DialogConfig; static createCustomConfig(title: string, message: string, options?: Partial): DialogConfig; } ``` ## 🔧 实际使用示例 查看 `EncapsulationDemo.ets` 文件获取完整的使用示例: ### 基础弹窗类型 ```typescript // 信息弹窗 private showInfo(title: string, message: string): void { const config: DialogConfig = { title, message, confirmText: '知道了', titleColor: '#2196F3', confirmButtonColor: '#2196F3', showCancel: false }; this.showDialog(config); } // 确认弹窗 private showConfirm(title: string, message: string, onConfirm?: () => void, onCancel?: () => void): void { const config: DialogConfig = { title, message, confirmText: '确定', cancelText: '取消', titleColor: '#333333', confirmButtonColor: '#007AFF', cancelButtonColor: '#F5F5F5', showCancel: true, onConfirm, onCancel }; this.showDialog(config); } ``` ### 自定义弹窗 ```typescript private showCustomDialog(): void { const config: DialogConfig = { title: '个性化弹窗', message: '这是一个自定义样式的弹窗示例', confirmText: '太棒了', titleColor: '#E91E63', confirmButtonColor: '#E91E63', dialogWidth: 320, showCancel: false }; this.showDialog(config); } ``` ### 核心显示方法 ```typescript private showDialog(config: DialogConfig): void { // 关闭之前的弹窗 if (this.dialogController) { this.dialogController.close(); } // 创建新的弹窗控制器 this.dialogController = new CustomDialogController({ builder: SimpleDialog({ title: config.title || '', message: config.message || '', confirmText: config.confirmText || '确定', cancelText: config.cancelText || '取消', showCancel: config.showCancel || false, onConfirm: config.onConfirm, onCancel: config.onCancel, titleColor: config.titleColor || '#333333', messageColor: config.messageColor || '#666666', confirmButtonColor: config.confirmButtonColor || '#007AFF', cancelButtonColor: config.cancelButtonColor || '#F5F5F5', dialogWidth: config.dialogWidth || 300 }), alignment: DialogAlignment.Center, maskColor: config.maskColor || 'rgba(0, 0, 0, 0.5)', customStyle: true, autoCancel: true }); this.dialogController.open(); } ``` ## 🎨 预设主题 ### 信息弹窗 (INFO) - 颜色:蓝色 (#2196F3) - 按钮文字:知道了 - 单按钮显示 ### 成功弹窗 (SUCCESS) - 颜色:绿色 (#4CAF50) - 按钮文字:好的 - 单按钮显示 ### 警告弹窗 (WARNING) - 颜色:橙色 (#FF9800) - 按钮文字:知道了 - 单按钮显示 ### 错误弹窗 (ERROR) - 颜色:红色 (#F44336) - 按钮文字:确定 - 单按钮显示 ### 确认弹窗 (CONFIRM) - 颜色:深灰色 (#333333) - 按钮文字:确定/取消 - 双按钮显示 ## 🛠️ 技术架构 ### 设计模式 - **组件内部集成**:所有弹窗逻辑直接在使用的组件内部实现 - **配置驱动**:通过 `DialogConfig` 接口统一配置弹窗参数 - **工具类辅助**:提供 `DialogHelper` 简化常用配置创建 ### 关键技术点 1. **CustomDialogController 管理**:在组件内部创建和管理弹窗控制器 2. **类型安全**:完整的 TypeScript 接口定义 3. **ArkTS 规范**:完全符合 HarmonyOS ArkTS 语法要求 4. **生命周期管理**:在组件销毁时正确关闭弹窗 ## 🐛 问题解决记录 ### 问题1:对象字面量类型错误 **错误信息:** `Object literal must correspond to some explicitly declared class or interface` **解决方案:** 添加明确的接口定义,使用函数替代对象映射 ```typescript // ❌ 错误方式 const THEME_CONFIGS = { ... }; // ✅ 正确方式 function getThemeConfig(type: DialogType): ThemeConfig { ... } ``` ### 问题2:扩展运算符不支持 **错误信息:** `It is possible to spread only arrays or classes derived from arrays` **解决方案:** 使用显式属性赋值替代扩展运算符 ```typescript // ❌ 错误方式 const config = { ...baseConfig, ...options }; // ✅ 正确方式 const config = { ...baseConfig }; if (options.title !== undefined) config.title = options.title; ``` ### 问题3:margin 语法错误 **错误信息:** `'vertical' does not exist in type 'Padding'` **解决方案:** 使用标准的 margin 语法 ```typescript // ❌ 错误方式 .margin({ vertical: 20 }) // ✅ 正确方式 .margin({ top: 20, bottom: 20 }) ``` ### 问题4:运行时弹窗不显示 **错误信息:** `Cannot read property dialogController of undefined` **解决方案:** 将弹窗逻辑集成到组件内部,确保在正确的组件上下文中执行 ```typescript // ❌ 错误方式:使用外部 DialogManager 类 private dialog: DialogManager = new DialogManager(); // ✅ 正确方式:组件内部管理 private dialogController: CustomDialogController = ...; private showDialog(config: DialogConfig): void { ... } ``` ## 🎯 最佳实践 ### 1. 组件生命周期管理 ```typescript @Component export struct MyPage { private dialogController: CustomDialogController = ...; aboutToDisappear(): void { // 页面销毁时关闭弹窗,避免内存泄漏 if (this.dialogController) { this.dialogController.close(); } } } ``` ### 2. 错误处理示例 ```typescript private async handleNetworkRequest(): Promise { try { const result = await this.networkService.request(); this.showSuccess('请求成功', '数据已获取'); } catch (error) { if (error.code === 'NETWORK_ERROR') { this.showError('网络错误', '请检查网络连接'); } else if (error.code === 'PERMISSION_DENIED') { this.showWarning('权限不足', '请联系管理员'); } else { this.showError('未知错误', '请稍后重试'); } } } ``` ### 3. 异步操作处理 ```typescript private async handleDelete(): Promise { this.showConfirm( '删除确认', '确定要删除这个文件吗?删除后无法恢复。', async () => { try { await this.deleteFile(); this.showSuccess('删除成功', '文件已成功删除!'); } catch (error) { this.showError('删除失败', '删除操作失败,请重试'); } } ); } ``` ## 📝 注意事项 1. **组件上下文**:弹窗必须在组件内部创建和管理,不能跨组件使用 2. **生命周期**:建议在 `aboutToDisappear()` 中关闭弹窗 3. **异步操作**:在异步回调中使用弹窗时,确保组件仍然存活 4. **样式兼容**:确保自定义颜色在深色模式下的兼容性 5. **性能考虑**:频繁显示弹窗时注意及时关闭之前的实例 ## 🔍 调试技巧 ### 1. 添加日志 ```typescript private showDialog(config: DialogConfig): void { console.info('显示弹窗:', config.title); // ... 弹窗逻辑 } ``` ### 2. 检查组件状态 ```typescript Button('测试弹窗') .onClick(() => { console.info('按钮被点击'); this.showInfo('测试', '弹窗功能正常'); }); ``` ### 3. 捕获错误 ```typescript private showDialog(config: DialogConfig): void { try { // 弹窗创建逻辑 this.dialogController.open(); } catch (error) { console.error('弹窗显示失败:', error); } } ``` ## 🚀 版本历史 ### v1.0.0 (最终版本) - ✅ 完全符合 ArkTS 规范 - ✅ 解决了所有编译错误 - ✅ 修复了运行时弹窗不显示问题 - ✅ 组件内部集成方案 - ✅ 完整的类型定义 - ✅ 5种预设弹窗样式 - ✅ 完全自定义支持 ### 开发过程中解决的问题 - 修复对象字面量类型错误 - 移除不支持的扩展运算符 - 修正 margin 语法错误 - 解决组件上下文访问问题 ## 🤝 贡献 欢迎提交 Issue 和 Pull Request 来改进这个组件。 ## 📄 许可证 MIT License --- **Happy Coding! 🎉** > 这个弹窗组件已经在实际项目中验证,完全符合 HarmonyOS 开发规范,可以安全使用。