从登录注册到用户管理:用HarmonyOS ArkUI + 关系型数据库撸一个完整App
·
从登录到数据管理:HarmonyOS全栈应用开发实战
在移动应用开发领域,用户系统是最基础也最具代表性的功能模块之一。一个完整的用户系统不仅需要友好的界面交互,更需要可靠的数据存储和管理机制。本文将带你使用HarmonyOS的ArkUI框架和关系型数据库,从零构建一个包含登录、注册和用户管理功能的完整应用。
1. 环境准备与项目初始化
开发HarmonyOS应用首先需要配置好开发环境。最新版本的DevEco Studio提供了完善的工具链支持,包括代码编辑、调试和模拟器管理等功能。安装完成后,我们可以创建一个新的"UserManager"项目,选择"Empty Ability"模板。
项目初始化后,目录结构如下:
UserManager
├── entry
│ ├── src/main
│ │ ├── ets
│ │ │ ├── Application
│ │ │ ├── entryability
│ │ │ └── pages
│ │ ├── resources
│ │ └── module.json5
└── oh-package.json5
在开始编码前,我们需要在oh-package.json5中添加数据库依赖:
"dependencies": {
"@kit.ArkData": "^1.0.0"
}
2. 数据库设计与实现
关系型数据库是用户系统的核心,HarmonyOS提供了@kit.ArkData模块来操作SQLite数据库。我们首先设计用户表结构:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | INTEGER | 主键,自增长 |
| username | TEXT | 用户名,非空 |
| password | TEXT | 密码,非空 |
| mobile | TEXT | 手机号 |
创建数据库工具类DBTools.ets,封装常用操作:
import { relationalStore } from '@kit.ArkData';
export default class DBTools {
private static rdbStore: relationalStore.RdbStore;
// 初始化数据库
static async initDB(context: Context) {
const config = {
name: 'user_db.db',
securityLevel: relationalStore.SecurityLevel.S3
};
this.rdbStore = await relationalStore.getRdbStore(context, config);
await this.rdbStore.executeSql(
'CREATE TABLE IF NOT EXISTS USER(' +
'ID INTEGER PRIMARY KEY AUTOINCREMENT, ' +
'USERNAME TEXT NOT NULL, ' +
'PASSWORD TEXT NOT NULL, ' +
'MOBILE TEXT)'
);
}
// 用户注册
static async register(user: {username: string, password: string}) {
const valueBucket = {
'username': user.username,
'password': user.password
};
return this.rdbStore.insert('USER', valueBucket);
}
// 用户登录验证
static async login(username: string, password: string) {
const predicates = new relationalStore.RdbPredicates('USER');
predicates.equalTo('username', username)
.and()
.equalTo('password', password);
return this.rdbStore.query(predicates);
}
}
3. 页面设计与实现
3.1 登录页面
登录页面是用户系统的入口,我们使用TextInput组件接收用户输入,Button组件触发登录操作:
@Entry
@Component
struct LoginPage {
@State username: string = '';
@State password: string = '';
build() {
Column() {
Text('用户登录').fontSize(26).margin({bottom: 30})
TextInput({placeholder: '请输入用户名'})
.width('80%')
.onChange((value) => {
this.username = value;
})
TextInput({placeholder: '请输入密码'})
.type(InputType.Password)
.width('80%')
.onChange((value) => {
this.password = value;
})
Button('登录', {type: ButtonType.Capsule})
.width('80%')
.margin({top: 20})
.onClick(async () => {
const result = await DBTools.login(this.username, this.password);
if (result.rowCount > 0) {
router.pushUrl({url: 'pages/UserList'});
} else {
promptAction.showToast({message: '用户名或密码错误'});
}
})
Button('去注册', {type: ButtonType.Text})
.margin({top: 10})
.onClick(() => {
router.pushUrl({url: 'pages/Register'});
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
3.2 注册页面
注册页面结构与登录类似,但增加了密码确认和手机号字段:
@Entry
@Component
struct RegisterPage {
@State username: string = '';
@State password: string = '';
@State confirmPwd: string = '';
@State mobile: string = '';
build() {
Column() {
Text('用户注册').fontSize(26).margin({bottom: 30})
// 用户名输入框
TextInput({placeholder: '设置用户名'})
.width('80%')
.onChange((value) => {
this.username = value;
})
// 密码输入框
TextInput({placeholder: '设置密码'})
.type(InputType.Password)
.width('80%')
.onChange((value) => {
this.password = value;
})
// 确认密码
TextInput({placeholder: '确认密码'})
.type(InputType.Password)
.width('80%')
.onChange((value) => {
this.confirmPwd = value;
})
// 手机号
TextInput({placeholder: '手机号'})
.width('80%')
.onChange((value) => {
this.mobile = value;
})
Button('注册', {type: ButtonType.Capsule})
.width('80%')
.margin({top: 20})
.onClick(async () => {
if (this.password !== this.confirmPwd) {
promptAction.showToast({message: '两次密码不一致'});
return;
}
try {
await DBTools.register({
username: this.username,
password: this.password
});
promptAction.showToast({message: '注册成功'});
router.back();
} catch (e) {
promptAction.showToast({message: '注册失败'});
}
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
3.3 用户列表页面
登录成功后展示用户列表,使用Grid组件实现卡片式布局:
@Entry
@Component
struct UserListPage {
@State users: Array<{
id: number,
username: string,
mobile: string
}> = [];
aboutToAppear() {
this.loadUsers();
}
async loadUsers() {
const predicates = new relationalStore.RdbPredicates('USER');
const result = await DBTools.rdbStore.query(predicates, ['id', 'username', 'mobile']);
this.users = [];
while (result.goToNextRow()) {
this.users.push({
id: result.getLong(result.getColumnIndex('id')),
username: result.getString(result.getColumnIndex('username')),
mobile: result.getString(result.getColumnIndex('mobile')) || '未设置'
});
}
}
build() {
Column() {
Text('用户列表').fontSize(26).margin({bottom: 20})
Grid() {
ForEach(this.users, (user) => {
GridItem() {
Column() {
Text(user.username).fontSize(18)
Text(user.mobile).fontSize(14).margin({top: 5})
}
.padding(10)
.width('90%')
.borderRadius(10)
.backgroundColor(Color.White)
}
})
}
.columnsTemplate('1fr 1fr')
.rowsTemplate('1fr 1fr')
.height('70%')
.width('90%')
Button('退出登录', {type: ButtonType.Capsule})
.width('80%')
.margin({top: 20})
.onClick(() => {
router.back();
})
}
.width('100%')
.height('100%')
.padding(10)
.backgroundColor('#f5f5f5')
}
}
4. 功能优化与扩展
4.1 数据加密存储
用户密码应该加密存储,我们可以使用HarmonyOS的安全子系统提供的加密能力:
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
async function encryptPassword(password: string) {
const cipher = cryptoFramework.createCipher('AES256|ECB|PKCS7');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE,
await cryptoFramework.createSymKeyGenerator('AES256').generateSymKey());
const input = { data: stringToUint8Array(password) };
const output = await cipher.doFinal(input);
return uint8ArrayToString(output.data);
}
4.2 表单验证
在注册和登录时增加表单验证逻辑:
function validateRegister(user: {
username: string,
password: string,
confirmPwd: string,
mobile?: string
}) {
const errors = [];
if (!user.username || user.username.length < 4) {
errors.push('用户名至少4个字符');
}
if (!user.password || user.password.length < 6) {
errors.push('密码至少6个字符');
}
if (user.password !== user.confirmPwd) {
errors.push('两次密码不一致');
}
if (user.mobile && !/^1[3-9]\d{9}$/.test(user.mobile)) {
errors.push('手机号格式不正确');
}
return errors;
}
4.3 记住登录状态
使用Preferences实现记住登录状态功能:
import { preferences } from '@kit.ArkData';
const PREFERENCES_NAME = 'user_preferences';
async function saveLoginState(username: string) {
const prefs = await preferences.getPreferences(getContext(), PREFERENCES_NAME);
await prefs.put('lastLoginUser', username);
await prefs.flush();
}
async function getLastLoginUser() {
const prefs = await preferences.getPreferences(getContext(), PREFERENCES_NAME);
return prefs.get('lastLoginUser', '');
}
5. 项目构建与测试
完成开发后,我们可以通过DevEco Studio的模拟器进行测试:
- 在DevEco Studio工具栏选择"Tools > Device Manager"
- 创建或启动一个HarmonyOS模拟器
- 点击运行按钮,选择目标设备
测试流程建议:
- 首次启动应显示登录页面
- 点击"去注册"跳转到注册页面
- 注册新用户后自动返回登录页面
- 使用新注册的用户登录
- 验证用户列表是否正确显示
在开发过程中,可以使用hilog输出调试信息:
import { hilog } from '@kit.PerformanceAnalysisKit';
hilog.info(0x0000, 'UserManager', 'User login: %{public}s', username);
更多推荐


所有评论(0)