【引言】

本案例将实现一个随机密码生成器。用户可以自定义密码的长度以及包含的字符类型(大写字母、小写字母、数字、特殊字符),最后通过点击按钮生成密码,并提供一键复制功能。

【环境准备】

•操作系统:Windows 10
•开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.3.806
•目标设备:华为Mate60 Pro
•开发语言:ArkTS
•框架:ArkUI
•API版本:API 12

【项目结构】

本项目主要由一个入口组件PasswordGeneratorPage和一个可观察的类PasswordOption组成。PasswordOption类用于定义密码选项,包括选项名称、字符集、是否选中和是否启用的状态。

1. PasswordOption类

@ObservedV2
class PasswordOption {
name: string; // 选项名称
characters: string; // 该选项对应的字符集
@Trace selected: boolean = true; // 是否选中,默认为true
@Trace enabled: boolean = true; // 是否启用,默认为true constructor(name: string, characters: string) {
this.name = name;
this.characters = characters;
}
}

2. PasswordGeneratorPage组件

该组件包含密码选项、密码长度设置、生成密码和复制密码的功能。

@Entry
@Component
struct PasswordGeneratorPage {
@State options: PasswordOption[] = [
new PasswordOption("大写字母", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
new PasswordOption("小写字母", "abcdefghijklmnopqrstuvwxyz"),
new PasswordOption("数字", "0123456789"),
new PasswordOption("特殊字符", "!@#$%^&*()_+-=[]{}|;:,.<>?"),
];
@State passwordLength: number = 10; // 默认密码长度
@State generatedPassword: string = ''; // 生成的密码 // 生成密码的方法
generatePassword() {
let characterSet = '';
for (let option of this.options) {
if (option.selected) {
characterSet += option.characters;
}
}
let password = '';
for (let i = 0; i < this.passwordLength; i++) {
const randomIndex = Math.floor(Math.random() * characterSet.length);
password += characterSet[randomIndex];
}
this.generatedPassword = password;
} // 复制到剪贴板的方法
copyToClipboard(text: string) {
const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text);
const systemPasteboard = pasteboard.getSystemPasteboard();
systemPasteboard.setData(pasteboardData);
promptAction.showToast({ message: '已复制' });
} // 构建页面布局的方法
build() {
// 页面布局代码...
}
}

功能实现

1. 生成密码

用户可以选择不同的字符集(大写字母、小写字母、数字、特殊字符),并设置密码长度。点击“生成密码”按钮后,系统将根据选中的选项生成随机密码。

2. 复制密码

生成的密码可以通过点击“复制”按钮复制到剪贴板,用户将收到“已复制”的提示。

用户界面

用户界面采用了简洁的设计,包含标题、密码长度设置、选项选择、生成密码按钮和复制按钮。通过动态生成选项的UI元素,用户可以方便地选择所需的字符集。

总结

本文介绍了如何使用鸿蒙NEXT框架开发一个随机密码生成器。通过简单的代码实现,我们可以快速构建出实用的功能。希望这个案例能为你的开发提供灵感和帮助。

【完整代码】

// 导入剪贴板服务
import { pasteboard } from '@kit.BasicServicesKit';
// 导入弹窗提示服务
import { promptAction } from '@kit.ArkUI'; // 使用装饰器定义一个可观察的类,用于密码选项
@ObservedV2
class PasswordOption {
name: string; // 选项名称
characters: string; // 该选项对应的字符集
// 定义是否选中,默认为true
@Trace selected: boolean = true;
// 定义是否启用,默认为true
@Trace enabled: boolean = true; // 构造函数,初始化name和characters
constructor(name: string, characters: string) {
this.name = name;
this.characters = characters;
}
} // 使用装饰器定义一个入口组件
@Entry
@Component
struct PasswordGeneratorPage {
// 定义密码选项数组
@State options: PasswordOption[] = [
new PasswordOption("大写字母", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
new PasswordOption("小写字母", "abcdefghijklmnopqrstuvwxyz"),
new PasswordOption("数字", "0123456789"),
new PasswordOption("特殊字符", "!@#$%^&*()_+-=[]{}|;:,.<>?"),
];
// 定义密码长度状态,默认值为10
@State passwordLength: number = 10;
// 基础间距
@State baseSpacing: number = 30;
// 生成的密码
@State generatedPassword: string = '';
// 是否启用复制按钮
@State isCopyButtonEnabled: boolean = false;
// 主题色
@State primaryColor: string = '#71dec7';
// 字体颜色
@State fontColor: string = "#2e2e2e"; // 生成密码的方法
generatePassword() {
let characterSet = ''; // 初始化字符集合
// 遍历所有选项,如果选项被选中则加入字符集合
for (let option of this.options) {
if (option.selected) {
characterSet += option.characters
}
}
let password = ''; // 初始化密码字符串
// 根据密码长度生成随机密码
for (let i = 0; i < this.passwordLength; i++) {
const randomIndex = Math.floor(Math.random() * characterSet.length);
password += characterSet[randomIndex];
}
this.generatedPassword = password; // 更新生成的密码
} // 复制到剪贴板的方法
copyToClipboard(text: string) {
const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); // 创建剪贴板数据
const systemPasteboard = pasteboard.getSystemPasteboard(); // 获取系统剪贴板
systemPasteboard.setData(pasteboardData); // 将数据放入剪切板
promptAction.showToast({ message: '已复制' }); // 显示复制成功的提示
} // 检查选项选择状态的方法
checkOptionsSelection() {
let selectedCount = 0; // 记录已选中的选项数量
let lastSelectedIndex = 0; // 记录最后一个选中的选项索引
// 遍历所有选项
for (let i = 0; i < this.options.length; i++) {
this.options[i].enabled = true; // 默认启用所有选项
if (this.options[i].selected) {
lastSelectedIndex = i; // 更新最后一个选中的选项索引
selectedCount++; // 增加选中计数
}
}
// 如果只有一个选项被选中,则禁用该选项防止其被取消选中
if (selectedCount === 1) {
this.options[lastSelectedIndex].enabled = false;
}
} // 构建页面布局的方法
build() {
Column() {
// 标题栏
Text("随机密码生成")
.width('100%')// 设置宽度为100%
.height(54)// 设置高度为54
.fontSize(18)// 设置字体大小
.fontWeight(600)// 设置字体粗细
.backgroundColor(Color.White)// 设置背景颜色
.textAlign(TextAlign.Center)// 设置文本居中对齐
.fontColor(this.fontColor); // 设置字体颜色 // 密码长度设置部分
Column() {
Row() {
Text(`密码长度:`)// 密码长度标签
.fontWeight(600)
.fontSize(18)
.fontColor(this.fontColor);
Text(`${this.passwordLength}`)// 显示当前密码长度
.fontWeight(600)
.fontSize(18)
.fontColor(this.primaryColor);
}
.margin({ top: `${this.baseSpacing}lpx`, left: `${this.baseSpacing}lpx` }); // 滑动条设置密码长度
Row() {
Text('4').fontColor(this.fontColor).width(20);
Slider({
value: this.passwordLength, // 当前值
min: 4, // 最小值
max: 32, // 最大值
style: SliderStyle.InSet // 滑动条样式
})
.layoutWeight(1)// 布局权重
.blockColor(Color.White)// 滑块颜色
.trackColor('#EBEBEB')// 轨道颜色
.trackThickness(30)// 轨道厚度
.blockSize({ width: 55, height: 55 })// 滑块大小
.selectedColor(this.primaryColor)// 选中颜色
.onChange((value: number, mode: SliderChangeMode) => {
this.passwordLength = value; // 更新密码长度
console.info('value:' + value + 'mode' + mode.toString); // 打印日志
});
Text('32').fontColor(this.fontColor).width(20);
}.margin({
left: `${this.baseSpacing}lpx`,
right: `${this.baseSpacing}lpx`,
top: `${this.baseSpacing}lpx`,
}); // 选项设置部分
Text('选项')
.fontWeight(600)
.fontSize(18)
.fontColor(this.fontColor)
.margin({ left: `${this.baseSpacing}lpx`, top: `${this.baseSpacing}lpx`, bottom: `${this.baseSpacing}lpx` }); // 动态生成每个选项的UI元素
ForEach(this.options, (option: PasswordOption, index: number) => {
Row() {
Text(option.name)// 选项名称
.fontWeight(400)
.fontSize(16)
.fontColor(this.fontColor)
.layoutWeight(1);
Toggle({ type: ToggleType.Switch, isOn: option.selected })// 切换按钮
.width('100lpx')
.height('50lpx')
.enabled(option.enabled)// 是否启用切换
.selectedColor(this.primaryColor)
.onChange((isOn: boolean) => {
option.selected = isOn; // 更新选项状态
this.checkOptionsSelection(); // 检查选项选择状态
});
}
.width('100%')
.padding({
left: `${this.baseSpacing}lpx`,
right: `${this.baseSpacing}lpx`,
top: `${this.baseSpacing / 3}lpx`,
bottom: `${this.baseSpacing / 3}lpx`
})
.hitTestBehavior(HitTestMode.Block)
.onClick(() => {
if (option.enabled) {
option.selected = !option.selected; // 切换选项状态
}
});
}); // 生成密码按钮
Text('生成密码')
.fontColor(Color.White)
.backgroundColor(this.primaryColor)
.height(54)
.textAlign(TextAlign.Center)
.borderRadius(10)
.fontSize(18)
.width(`${650 - this.baseSpacing * 2}lpx`)
.margin({
top: `${this.baseSpacing}lpx`,
left: `${this.baseSpacing}lpx`,
right: `${this.baseSpacing}lpx`,
bottom: `${this.baseSpacing}lpx`
})
.clickEffect({ level: ClickEffectLevel.HEAVY, scale: 0.8 })// 点击效果
.onClick(() => {
this.generatePassword(); // 生成密码
});
}
.width('650lpx')
.margin({ top: 20 })
.backgroundColor(Color.White)
.borderRadius(10)
.alignItems(HorizontalAlign.Start); // 显示生成的密码
Column() {
Text(`密码结果:`)
.fontWeight(600)
.fontSize(18)
.fontColor(this.fontColor)
.margin({
top: `${this.baseSpacing}lpx`,
left: `${this.baseSpacing}lpx`,
});
Text(`${this.generatedPassword}`)// 显示生成的密码
.width('650lpx')
.fontColor(this.primaryColor)
.fontSize(18)
.textAlign(TextAlign.Center)
.padding({ left: 5, right: 5 })
.margin({
top: `${this.baseSpacing / 3}lpx`
}); // 复制按钮
Text('复制')
.enabled(this.generatedPassword ? true : false)// 只有生成了密码才启用复制按钮
.fontColor(Color.White)
.backgroundColor(this.primaryColor)
.height(54)
.textAlign(TextAlign.Center)
.borderRadius(10)
.fontSize(18)
.width(`${650 - this.baseSpacing * 2}lpx`)
.margin({
top: `${this.baseSpacing}lpx`,
left: `${this.baseSpacing}lpx`,
right: `${this.baseSpacing}lpx`,
bottom: `${this.baseSpacing}lpx`
})
.clickEffect({ level: ClickEffectLevel.HEAVY, scale: 0.8 })
.onClick(() => {
this.copyToClipboard(this.generatedPassword); // 复制密码
});
}
.width('650lpx')
.backgroundColor(Color.White)
.borderRadius(10)
.margin({ top: `${this.baseSpacing}lpx` })
.alignItems(HorizontalAlign.Start);
}
.height('100%')
.width('100%')
.backgroundColor("#f2f3f5"); // 页面背景颜色
}
}

  

鸿蒙NEXT开发案例:随机密码生成的更多相关文章

  1. 最全华为鸿蒙 HarmonyOS 开发资料汇总

    开发 本示例基于 OpenHarmony 下的 JavaScript UI 框架,进行项目目录解读,JS FA.常用和自定义组件.用户交互.JS 动画的实现,通过本示例可以基本了解和学习到 JavaS ...

  2. SpringBoot开发案例从0到1构建分布式秒杀系统

    前言 ​最近,被推送了不少秒杀架构的文章,忙里偷闲自己也总结了一下互联网平台秒杀架构设计,当然也借鉴了不少同学的思路.俗话说,脱离案例讲架构都是耍流氓,最终使用SpringBoot模拟实现了部分秒杀场 ...

  3. 大数据技术之_09_Flume学习_Flume概述+Flume快速入门+Flume企业开发案例+Flume监控之Ganglia+Flume高级之自定义MySQLSource+Flume企业真实面试题(重点)

    第1章 Flume概述1.1 Flume定义1.2 Flume组成架构1.2.1 Agent1.2.2 Source1.2.3 Channel1.2.4 Sink1.2.5 Event1.3 Flum ...

  4. 《实战突击:PHP项目开发案例整合(第2版)(含DVD光盘1张)》

    <实战突击:PHP项目开发案例整合(第2版)(含DVD光盘1张)> 基本信息 作者: 徐康明    辛洪郁 出版社:电子工业出版社 ISBN:9787121221378 上架时间:2014 ...

  5. JAVA WEB项目开发案例精粹

    http://www.blogjava.net/zongbao/archive/2012/07/24/383884.htmlJAVA WEB项目开发案例精粹.pdf main Alt + / => ...

  6. 基于JWT的Token开发案例

    代码地址如下:http://www.demodashi.com/demo/12531.html 0.准备工作 0-1运行环境 jdk1.8 maven 一个能支持以上两者的代码编辑器,作者使用的是ID ...

  7. 前端到后台ThinkPHP开发整站--php开发案例

    前端到后台ThinkPHP开发整站--php开发案例 总结 还是需要做几个案例,一天一个为佳,那样才能做得快. 从需求分析着手,任务体系要构建好,这样才能非常高效. 转自: 前端到后台ThinkPHP ...

  8. Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息)

    推荐阅读:Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)​ 需求分析 我们假设有一个需求,我在后端点击按钮 1,首页弹出 “后端触发了按钮 1”.后端点了 ...

  9. 从微信小程序到鸿蒙js开发【15】——JS调用Java

    鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 目录:1.新建一个Service Ability2.完善代码逻辑3.JS端远程调用4.<从微信小 ...

  10. 使用Jquery+EasyUI 进行框架项目开发案例讲解之五 模块(菜单)管理源码分享

    http://www.cnblogs.com/huyong/p/3454012.html 使用Jquery+EasyUI 进行框架项目开发案例讲解之五  模块(菜单)管理源码分享    在上四篇文章 ...

随机推荐

  1. 修改kubeadm证书过期时间及更新k8s集群证书

    一.为什么要修改 kubeadm 证书时间 Kubernetes 官方提供了 kubeadm 工具安装 kubernetes 集群,使用这个工具安装集群非常便捷,使部署和升级 Kubernetes 变 ...

  2. Ubuntu 添加虚拟内存文件

    添加交换文件 准备工作 查看当前系统中启用的交换空间(swap space)的详细信息: sudo swapon --show 查看系统的内存和总交换空间的使用情况: free -h 为了有足够的空间 ...

  3. 一文了解JSON

    目录 JSON 在JavaScript 中的使用. json 的定义 json 的访问 json 的两个常用方法 JSON 在 在 java 中的使用 javaBean 和 和 json 的互转 Li ...

  4. Seata 四大模式详解

    分布式事务 参考文章: 分布式事务实战方案汇总 https://www.cnblogs.com/yizhiamumu/p/16625677.html 分布式事务原理及解决方案案例https://www ...

  5. 【SpringBoot Demo】MySQL + JPA + Hibernate + Springboot + Maven Demo

    主要包含:springboot+jpa+hibernate+mysql+lombok (两年前写过一个,现在重新记录一个) 1. 目录结构: 2. pom 文件 1 <?xml version= ...

  6. 声明式 Shadow DOM:简化 Web 组件开发的新工具

    在现代 Web 开发中,Web 组件已经成为创建模块化.可复用 UI 组件的标准工具.而 Shadow DOM 是 Web 组件技术的核心部分,它允许开发人员封装组件的内部结构和样式,避免组件的样式和 ...

  7. HTML – Native Form 原生表单功能集

    前言 以前写过 form 表单, 但很不齐全, 这篇想做一个大整理. 主要讲讲在网站中使用原生 Form 的功能, 不足和扩展. 前端是原生的 HTML/JS, 后端是 ASP.NET Core Ra ...

  8. 算法与数据结构——AVL树(平衡二叉搜索树)

    AVL树 在"二叉搜索树"章节提到,在多次插入和删除操作后,二叉搜索树可能退化为链表.在这种情况下,所有操作的时间复杂度将从O(logn)劣化为O(n). 如下图,经过两次删除节点 ...

  9. 均值回归策略在A股ETF市场获利的可能性

    如何在股票市场获利 曾经有人告诉我一个在股票市场赚钱的秘诀,只要掌握这个秘诀,赚钱就像捡钱一样容易.他说:这个秘诀其实很简单,就是在股票价格低的时候买入,在价格高的时候卖出. 啧啧,不愧是秘诀,明明是 ...

  10. 共124篇!墨天轮“高可用架构”干货文档分享(含Oracle、MySQL、PG)

    大家期待的高可用篇来啦!在上期<墨天轮高分技术文档分享-Oracle升级迁移篇>中大家对数据库高可用架构相关文档呼声较高,这不就来啦! 数据库的高可用架构能够在发生宕机或意外中断等故障时起 ...