【引言】
本案例將實現一個隨機密碼生成器。使用者可以自定義密碼的長度以及包含的字元型別(大寫字母、小寫字母、數字、特殊字元),最後透過點選按鈕生成密碼,並提供一鍵複製功能。
【環境準備】
•作業系統: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"); // 頁面背景顏色 } }