鸿蒙开发实战:5分钟打造一个优雅的登录界面(OpenHarmony 5.0兼容版)
无需第三方资源,纯ArkUI组件构建专业级登录页面
在鸿蒙应用开发中,登录界面是每个应用的门面。今天我们将手把手教你如何用ArkUI在OpenHarmony 5.0上创建一个既美观又功能完整的登录界面,而且完全不需要依赖外部图标资源!
一、效果预览
我们先来看一下最终实现的登录界面效果:
- 渐变蓝色背景搭配白色登录卡片,简洁大气
- 完整的表单验证:用户名、密码必填验证,密码长度检查
- 多方式登录:账号密码登录 + 第三方登录选项
- 响应式交互:加载状态、记住我功能、忘记密码
- 完全兼容:专为OpenHarmony 5.0优化,无兼容性问题
二、核心代码实现
代码由 deepseek 生成
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
| import prompt from '@ohos.prompt';
@Entry @Component struct LoginPage { @State username: string = ''; @State password: string = ''; @State rememberMe: boolean = false; @State isLoading: boolean = false;
showToast(message: string) { console.info(message);
prompt.showToast({ message: message, duration: 2000 }); }
validateForm(): boolean { if (!this.username) { this.showToast('请输入用户名'); return false; } if (!this.password) { this.showToast('请输入密码'); return false; } if (this.password.length < 6) { this.showToast('密码长度至少6位'); return false; } return true; }
handleLogin() { if (!this.validateForm()) return;
this.isLoading = true; setTimeout(() => { this.isLoading = false; this.showToast('登录成功!'); }, 1500); }
build() { Column() { Column() { Text('👤') .fontSize(40) .margin({ bottom: 16 }) Text('欢迎登录') .fontSize(30) .fontWeight(FontWeight.Bold) .fontColor(Color.White) } .margin({ top: 60, bottom: 40 })
Column() { Row() { Text('👤') .fontSize(20) .margin({ right: 12 }) TextInput({ placeholder: '请输入用户名/手机号/邮箱' }) .width('85%') .height(50) .placeholderColor('#999') .caretColor('#007DFF') .onChange((value: string) => { this.username = value; }) } .width('90%') .margin({ top: 30, bottom: 15 })
Divider().strokeWidth(1).color('#eee').width('90%')
Row() { Text('🔒') .fontSize(20) .margin({ right: 12 }) TextInput({ placeholder: '请输入密码' }) .width('85%') .height(50) .type(InputType.Password) .placeholderColor('#999') .caretColor('#007DFF') .onChange((value: string) => { this.password = value; }) } .width('90%') .margin({ top: 15, bottom: 15 })
Divider().strokeWidth(1).color('#eee').width('90%')
Row() { Row() { Checkbox() .select(this.rememberMe) .onChange((value: boolean) => { this.rememberMe = value; }) .margin({ right: 8 }) Text('记住我') .fontSize(14) .fontColor('#666') } .onClick(() => { this.rememberMe = !this.rememberMe; })
Blank()
Text('忘记密码?') .fontSize(14) .fontColor('#007DFF') .onClick(() => { this.showToast('跳转到找回密码页面'); }) } .width('90%') .margin({ top: 15, bottom: 30 })
Button(this.isLoading ? '登录中...' : '登录') .width('90%') .height(45) .backgroundColor('#007DFF') .fontColor(Color.White) .fontSize(16) .fontWeight(FontWeight.Medium) .onClick(() => { this.handleLogin(); }) .opacity(this.isLoading ? 0.7 : 1) .stateEffect(!this.isLoading)
Row() { Divider().strokeWidth(1).color('#eee').width('30%') Text('其他登录方式') .fontSize(12) .fontColor('#999') .margin({ left: 10, right: 10 }) Divider().strokeWidth(1).color('#eee').width('30%') } .margin({ top: 30, bottom: 20 })
Row() { Column() { Text('微') .fontSize(16) .fontColor(Color.White) .fontWeight(FontWeight.Medium) } .width(40) .height(40) .backgroundColor('#07C160') .borderRadius(20) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) .margin({ right: 25 }) .onClick(() => { this.showToast('微信登录'); })
Column() { Text('Q') .fontSize(16) .fontColor(Color.White) .fontWeight(FontWeight.Medium) } .width(40) .height(40) .backgroundColor('#12B7F5') .borderRadius(20) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) .margin({ right: 25 }) .onClick(() => { this.showToast('QQ登录'); })
Column() { Text('📱') .fontSize(16) .fontColor(Color.White) } .width(40) .height(40) .backgroundColor('#FF9500') .borderRadius(20) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) .onClick(() => { this.showToast('手机验证码登录'); }) } .justifyContent(FlexAlign.Center) .margin({ bottom: 30 })
Row() { Text('还没有账号?') .fontSize(14) .fontColor('#666') Text('立即注册') .fontSize(14) .fontColor('#007DFF') .onClick(() => { this.showToast('跳转到注册页面'); }) } .margin({ bottom: 20 }) } .width('80%') .backgroundColor(Color.White) .borderRadius(16) .shadow({ radius: 20, color: '#1A000000', offsetX: 0, offsetY: 4 })
Text('© 2024 我的应用 v1.0.0') .fontSize(12) .fontColor(Color.White) .margin({ top: 40 }) .opacity(0.8) } .width('100%') .height('100%') .justifyContent(FlexAlign.Start) .backgroundColor('#007DFF') } }
|
三、运行效果

四、技术亮点
1. 完全兼容OpenHarmony 5.0
- 使用
select而非selected属性操作Checkbox
- 采用
prompt.showToast而非新的promptAction API
- 避免使用不支持的
linearGradientBackground
2. 零外部依赖
- 所有图标使用Unicode表情符号实现
- 无需准备任何图片资源文件
- 减小应用体积,提高加载速度
3. 完整的用户体验
- 表单实时验证
- 加载状态反馈
- 错误提示机制
- 多登录方式支持