目录
一、引言
二、开发前准备
(一)DevEco Studio 的安装
(二)DevEco Studio 的配置
(三)新建 ArkUI 项目
三、认识布局容器
(一)线性布局(Row/Column)
(二)弹性布局(Flex)
四、常用组件登场
(一)文本输入框(TextInput)
(二)按钮(Button)
(三)文本(Text)
五、构建登录页面
(一)搭建页面结构
(二)添加交互功能
六、优化与完善
(一)表单验证
(二)页面跳转优化
(三)集成后端 API 实现真实登录功能
七、总结回顾
一、引言

在鸿蒙应用开发的广袤天地里,ArkUI 就如同一位技艺精湛的工匠,为开发者们打造出通往用户界面的神奇桥梁。作为鸿蒙系统应用界面的核心 UI 开发框架,ArkUI 以其简洁的 UI 语法、丰富多样的 UI 组件、强大而灵动的动画机制以及灵活自如的事件交互等基础能力,成为开发者们实现创意的得力助手,满足了大家对 UI 界面开发的多样化需求 ,让无数精彩的应用界面得以诞生。
在日常使用的各类鸿蒙应用中,从简洁高效的办公应用,到绚丽多彩的娱乐应用,再到便捷实用的生活服务应用,ArkUI 的身影无处不在。它就像一个万能的魔法师,赋予每个应用独特的魅力和出色的用户体验。比如,在某款热门的音乐播放应用中,ArkUI 通过其强大的布局能力,将歌曲列表、播放控制按钮、歌词展示等元素巧妙地组合在一起,呈现出简洁而美观的界面,让用户能够轻松愉悦地享受音乐;又比如,在一款地图导航应用里,ArkUI 运用其丰富的组件和灵活的交互能力,实现了地图的流畅缩放、地点搜索、路线规划等功能,为用户的出行提供了极大的便利。
今天,我们就一起踏上探索之旅,通过使用 ArkUI 的布局容器和常用组件,构建一个简单却实用的登录页面。这个过程不仅能让我们深入了解 ArkUI 的强大功能,还能为我们日后开发更复杂、更精彩的鸿蒙应用奠定坚实的基础。
二、开发前准备
正所谓 “工欲善其事,必先利其器” ,在正式开启构建登录页面的奇妙之旅前,我们得先把开发工具 DevEco Studio 准备好。它就像是我们打造应用世界的魔法工坊,为我们提供了一系列强大的功能和便捷的操作,让我们能够高效地进行鸿蒙应用开发。
(一)DevEco Studio 的安装
下载安装包:首先,打开你常用的浏览器,前往华为开发者官网,在那找到 DevEco Studio 的下载专区,根据你电脑的操作系统(Windows 或者 Mac),下载对应的安装包。这个过程就像是在知识的宝库中挑选一件珍贵的工具,虽然简单,但却至关重要。
安装过程:下载完成后,找到下载的安装包,双击运行它。接下来,就会弹出安装向导,它会一步一步引导你完成安装。在选择安装路径时,你可以选择默认路径,如果你对电脑磁盘空间有特殊规划,也可以点击 “Browse…” 按钮,指定其他你喜欢的路径,但要注意路径中不要出现中文或特殊字符,以免在后续开发过程中出现不必要的麻烦。接着,在安装选项界面,按照推荐的勾选方式进行勾选,然后一路点击 “Next”,直到安装完成。最后,点击 “Finish”,完成安装。这个过程就像是按照地图的指引,一步步走向目的地,只要你跟着向导的指示走,就能顺利完成安装。
(二)DevEco Studio 的配置
启动与协议同意:安装完成后,双击桌面上的 DevEco Studio 图标,启动这个魔法工坊。首次运行时,它会弹出一个配置向导页面,在这里,你需要点击 “Agree”,同意相关的条款和协议,就像是你在开启一场冒险前,要签署一份冒险契约,表明你愿意遵守规则,开启这段奇妙的开发之旅。
Node.js 与 Ohpm 配置:接下来,进入基础配置环节,你需要设置 Node.js 与 Ohpm 的安装路径。Ohpm 是 Open Harmony Package Management 的缩写,它就像是一个高效的管家,帮助我们管理项目中的各种包。如果你的电脑上已经安装了 Node.js,并且版本符合要求,可以选择 “Local”,指定 node 目录即可;要是电脑上已经有 Node.js,但版本不一致,建议选择让工具重新安装,以确保开发环境的稳定性;如果电脑上对 Node.js 做了一些特殊的 options 配置,为了避免冲突,建议先移除配置。另外,安装目录中不要出现中文、特殊字符,建议使用默认路径,这样可以减少很多潜在的问题。
SDK 配置:点击 “Next”,进入 SDK 配置页面。在这里,你要设置 SDK 的安装路径,同样要注意不要出现中文和特殊字符,建议走默认路径。设置好路径后,点击 “Next”,会显示 “SDK License Agreement”,仔细阅读相关协议后,勾选 “Accept”,表示你接受这些协议。然后,点击 “Next” 进入配置预览页,在这里你可以对之前的配置项进行确认,确保一切都符合你的预期。确认完成后,点击 “Next”,等待配置自动下载完成。完成后,点击 “Finish”,此时 IDE 会进入欢迎页,这就意味着你已经成功配置好了开发环境,是不是很有成就感呢?
环境错误处理:在安装和配置的过程中,可能会遇到一些小插曲。比如,如果出现类似 “Node.js 配置异常” 的错误,一般是因为你本地原本的 Node.js 配置有问题。这时,你可以清理环境变量中对于 Node.js 的配置,然后再次打开 DevEco Studio,点击界面左下方的 “?” 按钮,选择 “Diagnose Development Environment”,即诊断开发环境选项,进入诊断页面。这里会提示你安装出现问题的选项,点击异常项后面的 “set it up now” 即可重新安装。只要你耐心地按照提示进行操作,就能解决这些小问题,让开发环境顺利搭建起来。
(三)新建 ArkUI 项目
当 DevEco Studio 安装和配置完成后,就可以新建一个 ArkUI 项目啦。这就像是在一片空白的画布上,准备开始绘制一幅美丽的画卷。
创建项目:打开 DevEco Studio,在欢迎页面中,点击 “Create New Project”,就像你在打开一本新的笔记本,准备开始记录新的故事。
选择模板:在弹出的 “New Project” 窗口中,选择应用模板中的 “Empty Ability” 模板。这个模板就像是一个简单的素描底稿,为我们提供了一个最基础的项目结构,让我们可以在这个基础上自由发挥,添加各种功能和组件。选择好模板后,点击 “Next”。
填写项目信息:接下来,填写项目信息。其中 “Project name” 是你给项目取的名字,就像是给你的孩子取一个独特的名字,让它在众多项目中脱颖而出;“Bundle name” 是项目的包名,它就像是项目的身份证号码,用于唯一标识你的项目;“Save location” 是项目的保存路径,你可以选择一个你方便找到的地方来保存这个项目。填写好这些信息后,点击 “Finish”,完成创建。如果在创建过程中,你的电脑安装了杀毒软件,可能会弹出拦截提示,这时你只需点击允许程序的所有操作,就可以让项目顺利创建啦。
完成以上步骤后,一个全新的 ArkUI 项目就创建成功了,接下来,我们就可以在这个项目中大展身手,使用 ArkUI 的布局容器和常用组件,构建我们期待已久的登录页面了。
三、认识布局容器
在构建登录页面的过程中,布局容器就像是房屋的框架结构,决定了各个组件的摆放位置和排列方式,是打造美观、实用界面的关键所在。接下来,我们就来深入了解一下 ArkUI 中常用的布局容器。
(一)线性布局(Row/Column)
线性布局是 ArkUI 中最基础、最常用的布局方式之一,就像排列整齐的队列,它通过 Row 和 Column 这两个线性容器来实现,能让子元素在水平或垂直方向上依次排列 ,清晰又有条理。其中,Row 容器如同一条水平的轨道,使子元素从左到右横向排列,它的主轴是水平方向,交叉轴为垂直方向;而 Column 容器则像一个垂直的通道,让子元素从上到下纵向排列,它的主轴为垂直方向,交叉轴是水平方向。
线性布局在各种界面场景中都有着广泛的应用,比如在登录页面中,我们可以使用 Column 容器将页面的各个部分,如标题、输入框、按钮等,从上到下依次排列,形成一个清晰的视觉层次结构,让用户能够一目了然地找到他们需要的信息和操作按钮;当我们需要在一行中展示一些相关的小元素,如登录页面中的验证码输入框和获取验证码按钮,就可以使用 Row 容器将它们横向排列在一起,既节省空间又方便用户操作。
下面,我们通过一段代码示例来看看线性布局在登录页面结构搭建中的实际作用:
@Entry
@Component
struct LoginPage {
build() {
Column() {
// 登录页面标题
Text('用户登录')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ top: 50 })
// 账号输入框
Row() {
Text('账号:')
.width('25%')
.fontSize(18)
.textAlign(TextAlign.Right)
TextInput()
.width('70%')
.fontSize(18)
.placeholder('请输入账号')
}
.margin({ top: 30 })
// 密码输入框
Row() {
Text('密码:')
.width('25%')
.fontSize(18)
.textAlign(TextAlign.Right)
TextInput()
.width('70%')
.fontSize(18)
.placeholder('请输入密码')
.type(InputType.Password)
}
.margin({ top: 30 })
// 登录按钮
Button('登录')
.width('50%')
.height(50)
.fontSize(20)
.backgroundColor(Color.Blue)
.textColor(Color.White)
.margin({ top: 50 })
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
}
}
在这段代码中,最外层使用 Column 容器,就像搭建了一个垂直的框架,将整个登录页面的元素都包含在其中。在 Column 容器内部,首先是一个显示 “用户登录” 的 Text 组件,它作为页面的标题,通过设置字体大小、粗细和上边距,使其在页面上方居中显示,非常醒目。接着,通过两个 Row 容器分别构建了账号和密码输入框的布局。在每个 Row 容器中,左边是显示 “账号:” 或 “密码:” 的 Text 组件,设置了宽度、字体大小和右对齐方式,使其整齐地排列在左侧;右边是 TextInput 组件,用于用户输入账号和密码,设置了宽度、字体大小、占位符等属性,方便用户操作。密码输入框还通过type(InputType.Password)设置为密码输入模式,保护用户密码安全。最后,是一个 “登录” 按钮,同样使用 Button 组件,并设置了按钮的宽度、高度、字体大小、背景颜色、文本颜色和上边距等属性,使其在页面下方居中显示,吸引用户点击。通过这种方式,利用线性布局的 Row 和 Column 容器,我们成功地搭建起了一个简单而清晰的登录页面结构。
(二)弹性布局(Flex)
弹性布局(Flex)就像是一个充满智慧的空间管理者,它为开发者提供了一种更加灵活、高效的方式来排列、对齐和分配容器中的子元素空间,能够轻松应对各种复杂的布局需求,尤其是在处理响应式设计和动态布局时,它的优势更加明显。
在弹性布局中,容器默认存在主轴与交叉轴。主轴是 Flex 组件布局方向的轴线,子元素默认沿着主轴排列;交叉轴则是垂直于主轴方向的轴线。我们可以通过设置参数direction来决定主轴的方向,从而灵活控制子组件的排列方向。例如,FlexDirection.Row表示主轴为水平方向,子组件从起始端沿着水平方向开始排布,就像一排整齐排列的士兵;FlexDirection.RowReverse则是主轴为水平方向,但子组件从终点端沿着相反的方向开始排布,顺序颠倒;FlexDirection.Column意味着主轴为垂直方向,子组件从起始端沿着垂直方向开始排布,如同瀑布般垂直落下;FlexDirection.ColumnReverse是主轴为垂直方向,子组件从终点端沿着相反方向开始排布。
弹性布局还支持单行布局和多行布局。默认情况下,Flex 容器中的子元素都排在一条线(又称 “轴线”)上,即单行布局。当子元素主轴尺寸之和大于容器主轴尺寸时,wrap属性就发挥作用了,它可以控制 Flex 是单行布局还是多行布局。FlexWrap.NoWrap是默认值,表示不换行,如果子组件的宽度总和大于父元素的宽度,子组件就会被压缩宽度,以适应容器;FlexWrap.Wrap表示换行,每一行子组件按照主轴方向排列,就像书本上的文字,一行写满了就自动换到下一行;FlexWrap.WrapReverse同样是换行,但每一行子组件按照主轴反方向排列 。
在登录页面中,弹性布局有着独特的优势。比如,我们可以使用弹性布局轻松实现输入框和按钮的完美对齐,以及合理分配它们之间的空间。当页面大小发生变化时,弹性布局能够自动调整子元素的大小和位置,确保登录页面在不同设备和屏幕尺寸下都能保持良好的显示效果和用户体验。
下面是一段使用弹性布局构建登录页面部分元素的代码示例:
@Entry
@Component
struct LoginPage {
build() {
Flex({
direction: FlexDirection.Column,
justifyContent: FlexAlign.Center,
alignItems: ItemAlign.Center
}) {
// 登录页面标题
Text('用户登录')
.fontSize(30)
.fontWeight(FontWeight.Bold)
Flex({
direction: FlexDirection.Row,
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Center
}) {
// 账号输入框
TextInput()
.width('70%')
.fontSize(18)
.placeholder('请输入账号')
// 账号输入框右侧图标(假设)
Image($r('app.media.account_icon'))
.width(30)
.height(30)
}
.margin({ top: 30 })
Flex({
direction: FlexDirection.Row,
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Center
}) {
// 密码输入框
TextInput()
.width('70%')
.fontSize(18)
.placeholder('请输入密码')
.type(InputType.Password)
// 密码输入框右侧图标(假设)
Image($r('app.media.password_icon'))
.width(30)
.height(30)
}
.margin({ top: 30 })
// 登录按钮
Button('登录')
.width('50%')
.height(50)
.fontSize(20)
.backgroundColor(Color.Blue)
.textColor(Color.White)
}
.width('100%')
.height('100%')
}
}
在这段代码中,最外层的 Flex 容器设置了主轴方向为垂直方向(FlexDirection.Column),并通过justifyContent: FlexAlign.Center和alignItems: ItemAlign.Center使子元素在主轴和交叉轴方向都居中对齐,确保整个登录页面的元素在屏幕中心展示。在这个大容器内部,首先是 “用户登录” 的标题 Text 组件,简单而直接地表明页面主题。接着,使用了两个内部的 Flex 容器来分别构建账号和密码输入框的布局。这两个内部 Flex 容器的主轴方向都设置为水平方向(FlexDirection.Row),并且通过justifyContent: FlexAlign.SpaceBetween使输入框和右侧图标在水平方向上均匀分布,两端对齐,既美观又合理地利用了空间;alignItems: ItemAlign.Center则保证了输入框和图标在垂直方向上居中对齐。每个输入框设置了宽度、字体大小和占位符,密码输入框还设置为密码模式。最后,是 “登录” 按钮,设置了按钮的各种属性,使其在整个布局中显得协调统一。通过这样的弹性布局设置,登录页面的各个元素能够在不同的屏幕尺寸和设备上自适应调整,始终保持良好的视觉效果和用户交互体验。
四、常用组件登场
在布局容器搭建好登录页面的基本框架后,接下来就轮到常用组件闪亮登场了。这些组件就像是建筑中的各种装饰材料和家具,为登录页面增添了丰富的功能和交互性,让它从一个简单的框架变成一个真正可用的界面。下面,我们来认识一下构建登录页面必不可少的几个常用组件。
(一)文本输入框(TextInput)
文本输入框(TextInput)是登录页面中不可或缺的组件,它就像是一扇通往用户信息世界的大门,用于接收用户输入的用户名和密码等关键信息。在 ArkUI 中,TextInput 组件的功能十分强大,通过设置各种属性,我们可以让它满足不同的输入需求 。
在用户名和密码输入框的设置中,我们可以通过placeholder属性来设置提示文本,当输入框为空时,这些提示文本就会显示出来,引导用户输入正确的信息,比如 “请输入账号”“请输入密码”。对于密码输入框,为了保护用户的隐私安全,我们使用type(InputType.Password)将其设置为密码输入模式,这样用户输入的密码就会以掩码的形式显示,避免被他人轻易窥探。此外,maxLength属性可以用来限制用户输入的最大字符数,确保输入的信息符合规定的长度要求;fontSize属性用于设置输入文本的字体大小,让用户能够清晰地看到自己输入的内容;width属性则可以控制输入框的宽度,使其在页面中与其他组件的布局更加协调。
为了实时获取用户输入的内容,并进行相应的处理,比如验证用户输入的格式是否正确、是否为空等,我们可以使用onChange事件来监听输入框内容的变化。当用户在输入框中输入、删除或修改文本时,这个事件就会被触发,我们可以在事件处理函数中获取到最新的输入内容,并根据业务逻辑进行处理。例如:
@Entry
@Component
struct LoginPage {
@State username: string = '';
@State password: string = '';
build() {
Column() {
// 账号输入框
TextInput()
.placeholder('请输入账号')
.onChange((value: string) => {
this.username = value;
// 在这里可以添加对用户名的验证逻辑,比如判断是否为空
if (this.username === '') {
console.log('用户名不能为空');
}
})
.fontSize(18)
.width('70%');
// 密码输入框
TextInput()
.placeholder('请输入密码')
.type(InputType.Password)
.onChange((value: string) => {
this.password = value;
// 在这里可以添加对密码的验证逻辑,比如判断长度是否符合要求
if (this.password.length < 6) {
console.log('密码长度不能小于6位');
}
})
.fontSize(18)
.width('70%');
// 其他组件...
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center);
}
}
在这段代码中,我们定义了两个@State变量username和password,分别用于存储用户输入的用户名和密码。在两个 TextInput 组件中,通过onChange事件监听用户输入,将输入的值分别赋值给对应的变量,并在事件处理函数中添加了简单的验证逻辑,当用户名或密码不符合要求时,会在控制台输出相应的提示信息。通过这样的设置,我们能够有效地获取和处理用户在文本输入框中的输入,为后续的登录验证等操作做好准备。
(二)按钮(Button)
按钮(Button)在登录页面中扮演着至关重要的角色,它就像是一个启动开关,用户点击按钮后,就会触发相应的登录操作,将输入的用户名和密码发送到服务器进行验证,从而实现用户的登录功能。
在 ArkUI 中,我们可以通过多种方式来设置 Button 组件的样式,使其在页面中更加突出和美观,吸引用户的注意力。比如,使用width和height属性来控制按钮的宽度和高度,根据页面布局和设计需求,调整按钮的大小,使其与其他组件的比例协调;通过backgroundColor属性设置按钮的背景颜色,例如将登录按钮的背景颜色设置为醒目的蓝色,当按钮被点击时,还可以通过动画效果改变背景颜色,给予用户即时的反馈,增强交互体验;textColor属性用于设置按钮上文本的颜色,一般会选择与背景颜色形成鲜明对比的颜色,如白色,这样可以让文本更加清晰易读;fontSize属性则可以调整按钮文本的字体大小,使其在不同屏幕尺寸下都能清晰显示。此外,我们还可以通过border属性为按钮添加边框,设置边框的宽度、颜色和样式,进一步丰富按钮的视觉效果;radius属性可以设置按钮的圆角半径,使按钮看起来更加圆润、柔和,符合现代的设计风格。
为了实现登录功能,我们需要为按钮添加点击事件处理函数。当用户点击按钮时,这个函数就会被调用,我们可以在函数中编写登录的逻辑代码,比如调用后端的接口,将用户输入的用户名和密码发送到服务器进行验证,并根据验证结果给出相应的提示,如 “登录成功” 或 “用户名或密码错误”。示例代码如下:
@Entry
@Component
struct LoginPage {
@State username: string = '';
@State password: string = '';
handleLogin() {
// 这里模拟登录验证逻辑,实际开发中需要调用后端接口
if (this.username === 'admin' && this.password === '123456') {
console.log('登录成功');
} else {
console.log('用户名或密码错误');
}
}
build() {
Column() {
// 账号输入框
TextInput()
.placeholder('请输入账号')
.onChange((value: string) => {
this.username = value;
})
.fontSize(18)
.width('70%');
// 密码输入框
TextInput()
.placeholder('请输入密码')
.type(InputType.Password)
.onChange((value: string) => {
this.password = value;
})
.fontSize(18)
.width('70%');
// 登录按钮
Button('登录')
.width('50%')
.height(50)
.fontSize(20)
.backgroundColor(Color.Blue)
.textColor(Color.White)
.onClick(() => {
this.handleLogin();
});
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center);
}
}
在这段代码中,我们定义了一个handleLogin函数,用于处理登录逻辑。在按钮的onClick事件处理函数中,调用了这个handleLogin函数。当用户点击 “登录” 按钮时,就会执行handleLogin函数中的代码,根据用户名和密码的匹配情况,在控制台输出相应的提示信息。通过这样的设置,按钮就成为了实现登录功能的关键交互元素,连接起了用户和系统之间的沟通桥梁。
(三)文本(Text)
文本(Text)组件在登录页面中有着不可或缺的作用,它就像是一个贴心的向导,通过显示各种提示信息,为用户提供清晰的操作指引,让用户能够顺利地完成登录流程。比如,在登录页面的顶部,我们可以使用一个较大字体、醒目的 Text 组件来显示 “用户登录” 字样,明确告知用户当前页面的功能;在输入框旁边,我们可以添加一些辅助说明文本,如 “账号为您注册时的手机号码或邮箱”“密码需包含字母和数字,长度不少于 6 位” 等,帮助用户正确输入信息。
此外,Text 组件还可以用于显示一些链接,比如 “忘记密码?”“注册新账号” 等,这些链接可以引导用户进行其他相关操作。当用户点击这些链接时,我们可以通过路由或其他方式跳转到相应的页面,为用户提供更多的功能和服务。
在设置 Text 组件的样式时,我们同样有丰富的选择。fontSize属性用于调整文本的字体大小,根据文本的重要性和在页面中的位置,设置合适的大小,重要的标题可以使用较大的字体,而辅助说明文本则可以使用相对较小的字体;fontWeight属性可以设置文本的字体粗细,通过将标题文本设置为加粗,使其更加突出显示;fontStyle属性用于设置字体样式,如正常、斜体等,通过不同的样式来区分不同类型的文本;textColor属性则决定了文本的颜色,我们可以根据页面的整体风格和配色方案,选择与背景颜色相协调且易于阅读的颜色,比如在白色背景上,使用黑色或深灰色的文本颜色。另外,textAlign属性可以设置文本的对齐方式,如左对齐、居中对齐、右对齐等,根据文本在页面中的布局需求进行合理设置,使页面看起来更加整齐、美观。例如:
@Entry
@Component
struct LoginPage {
build() {
Column() {
// 登录页面标题
Text('用户登录')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ top: 50 });
// 账号输入框
Row() {
Text('账号:')
.width('25%')
.fontSize(18)
.textAlign(TextAlign.Right);
TextInput()
.width('70%')
.fontSize(18)
.placeholder('请输入账号');
}
.margin({ top: 30 });
// 密码输入框
Row() {
Text('密码:')
.width('25%')
.fontSize(18)
.textAlign(TextAlign.Right);
TextInput()
.width('70%')
.fontSize(18)
.placeholder('请输入密码')
.type(InputType.Password);
}
.margin({ top: 30 });
// 登录按钮
Button('登录')
.width('50%')
.height(50)
.fontSize(20)
.backgroundColor(Color.Blue)
.textColor(Color.White)
.margin({ top: 50 });
// 忘记密码链接
Text('忘记密码?')
.fontSize(16)
.textColor(Color.Blue)
.decoration({ type: TextDecorationType.Underline })
.margin({ top: 20 })
.onClick(() => {
// 这里添加跳转到忘记密码页面的逻辑
console.log('跳转到忘记密码页面');
});
// 注册新账号链接
Text('注册新账号')
.fontSize(16)
.textColor(Color.Blue)
.decoration({ type: TextDecorationType.Underline })
.margin({ top: 10 })
.onClick(() => {
// 这里添加跳转到注册页面的逻辑
console.log('跳转到注册页面');
});
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center);
}
}
在这段代码中,我们展示了 Text 组件在登录页面中的多种应用。首先,使用一个 Text 组件显示 “用户登录” 标题,通过设置较大的字体大小和加粗的字体样式,使其在页面顶部非常醒目。然后,在账号和密码输入框旁边,分别使用 Text 组件显示 “账号:” 和 “密码:”,并设置了合适的宽度、字体大小和右对齐方式,与输入框的布局相得益彰。接着,在登录按钮下方,使用两个 Text 组件分别显示 “忘记密码?” 和 “注册新账号” 链接,通过设置蓝色的文本颜色和下划线装饰,模拟出超链接的效果,并为它们添加了点击事件处理函数,当用户点击时,会在控制台输出相应的提示信息,实际开发中可以在这里添加跳转到对应页面的逻辑代码。通过这些设置,Text 组件不仅为登录页面提供了丰富的文本信息,还增强了页面的交互性和用户体验。
五、构建登录页面
(一)搭建页面结构
现在,我们已经对布局容器和常用组件有了深入的了解,接下来就可以正式开始构建登录页面了。在这个过程中,我们将综合运用之前所学的知识,打造一个简洁、美观且功能齐全的登录页面。
首先,我们使用 Column 线性布局容器来构建页面的整体框架,让页面元素能够垂直排列,形成清晰的视觉层次。在 Column 容器内部,我们依次添加标题、账号输入框、密码输入框和登录按钮等组件。
对于标题,我们使用 Text 组件显示 “用户登录” 字样,并通过设置fontSize属性为 30,fontWeight属性为FontWeight.Bold,让标题字体更大、更醒目,突出页面主题;同时,设置margin属性的top值为 50,使标题与页面顶部保持一定的距离,避免过于拥挤。
账号和密码输入框部分,我们分别使用 Row 容器来布局。在每个 Row 容器中,左边放置显示 “账号:” 或 “密码:” 的 Text 组件,设置其width属性为 25%,fontSize属性为 18,textAlign属性为TextAlign.Right,让文本右对齐,与输入框的布局更加协调;右边则是 TextInput 组件,用于用户输入账号和密码,设置width属性为 70%,fontSize属性为 18,placeholder属性分别为 “请输入账号” 和 “请输入密码”,方便用户了解输入要求。密码输入框还通过type(InputType.Password)设置为密码输入模式,保护用户密码安全。为了让输入框之间有适当的间距,我们为每个包含输入框的 Row 容器设置margin属性的top值为 30。
最后是登录按钮,使用 Button 组件,并设置width属性为 50%,height属性为 50,fontSize属性为 20,backgroundColor属性为Color.Blue,textColor属性为Color.White,使按钮在页面中更加突出,吸引用户点击;同时,设置margin属性的top值为 50,让按钮与上方的输入框保持合适的距离。
为了使整个登录页面在屏幕中居中显示,我们为最外层的 Column 容器设置width属性为 100%,height属性为 100%,并通过alignItems(HorizontalAlign.Center)使子元素在水平方向上居中对齐。
以下是完整的构建登录页面结构的代码:
@Entry
@Component
struct LoginPage {
build() {
Column() {
// 登录页面标题
Text('用户登录')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ top: 50 })
// 账号输入框
Row() {
Text('账号:')
.width('25%')
.fontSize(18)
.textAlign(TextAlign.Right)
TextInput()
.width('70%')
.fontSize(18)
.placeholder('请输入账号')
}
.margin({ top: 30 })
// 密码输入框
Row() {
Text('密码:')
.width('25%')
.fontSize(18)
.textAlign(TextAlign.Right)
TextInput()
.width('70%')
.fontSize(18)
.placeholder('请输入密码')
.type(InputType.Password)
}
.margin({ top: 30 })
// 登录按钮
Button('登录')
.width('50%')
.height(50)
.fontSize(20)
.backgroundColor(Color.Blue)
.textColor(Color.White)
.margin({ top: 50 })
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
}
}
通过以上代码,我们成功搭建起了登录页面的基本结构,各个组件在布局容器的组织下,排列整齐、层次分明,为后续添加交互功能奠定了坚实的基础。
(二)添加交互功能
有了登录页面的基本结构后,接下来就要为其添加交互功能,让页面真正 “活” 起来,实现与用户的有效互动。
首先,我们要实现用户名和密码输入的监听功能,以便实时获取用户输入的内容,并进行相应的处理。在前面的代码中,我们已经为 TextInput 组件添加了onChange事件监听函数,当用户在输入框中输入、删除或修改文本时,这个事件就会被触发。我们可以在事件处理函数中获取到最新的输入内容,并将其存储到对应的@State变量中。例如:
@Entry
@Component
struct LoginPage {
@State username: string = '';
@State password: string = '';
build() {
Column() {
// 账号输入框
TextInput()
.placeholder('请输入账号')
.onChange((value: string) => {
this.username = value;
})
.fontSize(18)
.width('70%');
// 密码输入框
TextInput()
.placeholder('请输入密码')
.type(InputType.Password)
.onChange((value: string) => {
this.password = value;
})
.fontSize(18)
.width('70%');
// 其他组件...
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center);
}
}
在这段代码中,我们定义了@State变量username和password,分别用于存储用户输入的用户名和密码。在账号和密码输入框的onChange事件处理函数中,将用户输入的值赋值给对应的变量,这样我们就能够随时获取到用户输入的最新内容,为后续的登录验证等操作做好准备。
接下来,实现登录按钮的点击验证功能。当用户点击登录按钮时,我们需要检查用户输入的用户名和密码是否正确。在实际开发中,这通常需要与后端服务器进行交互,验证用户的身份信息。但在这里,我们先进行简单的模拟验证,假设用户名是 “admin”,密码是 “123456”,如果用户输入的内容与之匹配,则提示 “登录成功”,否则提示 “用户名或密码错误”。实现代码如下:
@Entry
@Component
struct LoginPage {
@State username: string = '';
@State password: string = '';
handleLogin() {
if (this.username === 'admin' && this.password === '123456') {
console.log('登录成功');
} else {
console.log('用户名或密码错误');
}
}
build() {
Column() {
// 账号输入框
TextInput()
.placeholder('请输入账号')
.onChange((value: string) => {
this.username = value;
})
.fontSize(18)
.width('70%');
// 密码输入框
TextInput()
.placeholder('请输入密码')
.type(InputType.Password)
.onChange((value: string) => {
this.password = value;
})
.fontSize(18)
.width('70%');
// 登录按钮
Button('登录')
.width('50%')
.height(50)
.fontSize(20)
.backgroundColor(Color.Blue)
.textColor(Color.White)
.onClick(() => {
this.handleLogin();
});
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center);
}
}
在这段代码中,我们定义了handleLogin函数,用于处理登录逻辑。在按钮的onClick事件处理函数中,调用了handleLogin函数。当用户点击 “登录” 按钮时,就会执行handleLogin函数中的代码,根据用户名和密码的匹配情况,在控制台输出相应的提示信息。
最后,我们来模拟登录成功后的页面跳转功能。在实际应用中,当用户登录成功后,通常会跳转到应用的主页面或其他相关页面。在这里,我们使用router.pushUrl方法来模拟页面跳转,假设登录成功后跳转到 “pages/Home” 页面。要使用router.pushUrl方法,我们需要先导入router模块,代码如下:
import router from '@ohos.router';
@Entry
@Component
struct LoginPage {
@State username: string = '';
@State password: string = '';
handleLogin() {
if (this.username === 'admin' && this.password === '123456') {
console.log('登录成功');
router.pushUrl({
url: 'pages/Home'
});
} else {
console.log('用户名或密码错误');
}
}
build() {
Column() {
// 账号输入框
TextInput()
.placeholder('请输入账号')
.onChange((value: string) => {
this.username = value;
})
.fontSize(18)
.width('70%');
// 密码输入框
TextInput()
.placeholder('请输入密码')
.type(InputType.Password)
.onChange((value: string) => {
this.password = value;
})
.fontSize(18)
.width('70%');
// 登录按钮
Button('登录')
.width('50%')
.height(50)
.fontSize(20)
.backgroundColor(Color.Blue)
.textColor(Color.White)
.onClick(() => {
this.handleLogin();
});
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center);
}
}
在这段代码中,当用户登录成功后,除了在控制台输出 “登录成功” 信息外,还会调用router.pushUrl方法,跳转到指定的 “pages/Home” 页面,实现了简单的页面跳转功能。通过以上步骤,我们成功为登录页面添加了交互功能,使其具备了基本的登录验证和页面跳转能力,为用户提供了更加完善的使用体验。
六、优化与完善
通过前面的步骤,我们已经成功构建了一个简单的登录页面,具备了基本的布局和交互功能。然而,在实际应用开发中,为了提供更优质的用户体验和满足业务需求,我们还可以对这个登录页面进行多方面的优化与完善。
(一)表单验证
目前,我们的登录页面虽然能够获取用户输入的用户名和密码,但还没有对输入内容进行严格的验证。在实际场景中,表单验证是非常重要的环节,它可以确保用户输入的数据符合要求,提高数据的准确性和安全性。
对于用户名,常见的验证规则可能包括:不能为空,长度限制在一定范围内(比如 6 – 20 位),且只能包含字母、数字和特定的字符(如下划线)等。对于密码,要求可能更加严格,例如:长度至少为 8 位,必须包含大写字母、小写字母、数字和特殊字符(如!@#(%^&*等)。我们可以使用正则表达式来实现这些验证规则。例如,验证用户名的正则表达式可以是`/^[a-zA-Z0-9_]{6,20})/,验证密码的正则表达式可以是/^(?=.[a-z])(?=.[A-Z])(?=.d)(?=.[@(!%*?&])[A-Za-zd@)!%*?&]{8,}$/`。
在代码实现上,我们可以在handleLogin函数中添加这些验证逻辑。当用户点击登录按钮时,首先调用这些验证函数对用户名和密码进行验证,如果验证不通过,则提示用户相应的错误信息,阻止登录操作的进行。例如:
handleLogin() {
const usernameRegex = /^[a-zA-Z0-9_]{6,20}$/;
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[@$!%*?&])[A-Za-zd@$!%*?&]{8,}$/;
if (!usernameRegex.test(this.username)) {
console.log('用户名格式不正确,长度需在6 - 20位,且只能包含字母、数字和下划线');
return;
}
if (!passwordRegex.test(this.password)) {
console.log('密码格式不正确,长度至少为8位,需包含大写字母、小写字母、数字和特殊字符');
return;
}
// 验证通过,执行登录逻辑
if (this.username === 'admin' && this.password === '123456') {
console.log('登录成功');
router.pushUrl({
url: 'pages/Home'
});
} else {
console.log('用户名或密码错误');
}
}
通过这样的表单验证机制,我们可以有效地防止用户输入无效或不安全的数据,提升登录页面的可靠性和安全性。
(二)页面跳转优化
在当前的登录页面中,我们只是简单地模拟了登录成功后的页面跳转功能。在实际应用中,我们可能需要更加复杂和灵活的页面跳转逻辑。例如,当用户点击 “忘记密码?” 和 “注册新账号” 链接时,我们需要跳转到相应的页面,让用户能够进行密码找回和注册的操作。
为了实现这些功能,我们可以使用 ArkUI 提供的路由功能。首先,在项目的配置文件中,我们需要注册这些新页面的路由。例如,在config.json文件中,添加如下配置:
{
"pages": [
"pages/Login",
"pages/ForgetPassword",
"pages/Register"
]
}
这里假设我们已经创建了ForgetPassword和Register页面的相关文件。然后,在登录页面的代码中,为 “忘记密码?” 和 “注册新账号” 链接添加点击事件处理函数,使用router.pushUrl方法实现页面跳转。例如:
// 忘记密码链接
Text('忘记密码?')
.fontSize(16)
.textColor(Color.Blue)
.decoration({ type: TextDecorationType.Underline })
.margin({ top: 20 })
.onClick(() => {
router.pushUrl({
url: 'pages/ForgetPassword'
});
});
// 注册新账号链接
Text('注册新账号')
.fontSize(16)
.textColor(Color.Blue)
.decoration({ type: TextDecorationType.Underline })
.margin({ top: 10 })
.onClick(() => {
router.pushUrl({
url: 'pages/Register'
});
});
通过这样的优化,我们可以实现更加完善的页面跳转功能,为用户提供更加便捷的操作体验。
(三)集成后端 API 实现真实登录功能
目前,我们的登录逻辑只是简单地在前端进行了模拟验证,这在实际应用中是远远不够的。为了实现真正的用户登录功能,我们需要与后端服务器进行交互,将用户输入的用户名和密码发送到后端,由后端进行验证,并返回相应的结果。
在实际开发中,我们可以使用 HTTP 请求来与后端 API 进行通信。例如,使用fetch API 或者第三方库(如axios)来发送 POST 请求,将用户名和密码作为请求参数发送到后端的登录接口。后端接收到请求后,会根据存储在数据库中的用户信息进行验证,如果验证成功,则返回一个包含用户信息和令牌(Token)的响应;如果验证失败,则返回相应的错误信息。
在前端代码中,我们需要根据后端返回的结果进行相应的处理。如果登录成功,我们可以将用户信息和令牌存储在本地,以便后续的页面访问和用户认证;如果登录失败,我们需要提示用户错误原因,让用户重新输入。以下是使用fetch API 实现真实登录功能的示例代码:
handleLogin() {
const loginData = {
username: this.username,
password: this.password
};
fetch('https://api.example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(loginData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('登录成功');
// 存储用户信息和令牌
localStorage.setItem('userInfo', JSON.stringify(data.user));
localStorage.setItem('token', data.token);
router.pushUrl({
url: 'pages/Home'
});
} else {
console.log('用户名或密码错误');
}
})
.catch(error => {
console.error('登录请求失败:', error);
});
}
通过集成后端 API 实现真实登录功能,我们可以确保用户的身份验证是安全可靠的,同时也能够与后端的业务逻辑进行紧密的结合,为用户提供更加完整的应用服务。
七、总结回顾
通过本次探索,我们一起经历了使用 ArkUI 构建简单登录页面的全过程。从前期的开发环境搭建,到深入了解布局容器和常用组件的特性与使用方法,再到逐步构建登录页面的结构、添加交互功能以及最后的优化完善,每一步都让我们更加熟悉 ArkUI 这个强大的开发框架。
在布局容器的选择上,线性布局(Row/Column)为我们提供了基础且直观的排列方式,让页面元素能够按照水平或垂直方向有序排列;而弹性布局(Flex)则进一步提升了布局的灵活性,能够轻松应对各种复杂的布局需求和不同屏幕尺寸的适配。
常用组件如文本输入框(TextInput)、按钮(Button)和文本(Text),它们各自发挥着重要作用。TextInput 用于收集用户输入,Button 触发关键操作,Text 则负责传递信息和引导用户。通过合理设置它们的属性和事件,我们实现了登录页面的基本功能和交互体验。
在构建过程中,我们不断优化完善登录页面,从表单验证确保用户输入的准确性和安全性,到优化页面跳转逻辑提供更便捷的操作体验,再到集成后端 API 实现真实可靠的登录功能,每一次的优化都让登录页面更加贴近实际应用场景。
希望大家通过这篇文章,不仅掌握了构建登录页面的方法,更能感受到 ArkUI 开发框架的魅力和潜力。这只是一个简单的示例,ArkUI 还有更多丰富的功能和强大的特性等待着大家去探索。在未来的开发中,相信大家能够运用所学,结合实际需求,开发出更多精彩、实用的鸿蒙应用,为用户带来更加优质的体验。


















暂无评论内容