鸿蒙NEXT开发案例:随机密码生成

 

【引言】

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

【环境准备】

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

【项目结构】

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

1. PasswordOption类

1
2
3
4
5
6
7
8
9
10
11
12
@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组件

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@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框架开发一个随机密码生成器。通过简单的代码实现,我们可以快速构建出实用的功能。希望这个案例能为你的开发提供灵感和帮助。

【完整代码】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// 导入剪贴板服务
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"); // 页面背景颜色
  }
}

  

posted @   zhongcx  阅读(306)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示