鸿蒙 ArkTS 路由入门:由浅入深登录注册 Demo(从最简到完整业务)
·
前言
学习页面路由不用一次性啃完整业务代码,本文按照简易→进阶→完整业务的梯度分层讲解,从只实现跳转的极简页面,逐步增加传参、表单、校验逻辑,循序渐进掌握@ohos.router路由 API,新手更容易理解吸收。
前置统一配置(所有阶段都需要)
所有页面必须在main_pages.json注册,否则路由找不到页面,固定配置如下:
{
"src": [
"pages/Index",
"pages/second",
"pages/RouterDemo",
"pages/Resister",
"pages/LoginPage",
"pages/RouterLogin",
"pages/RouterRegister"
]
}
第一阶段:最简路由(仅页面跳转,无表单、无传参)
1.1 入口页面 RouterDemo.ets(路由总入口)
功能:只有两个文字,点击分别跳转到简易注册、简易登录,只用到最基础router.pushUrl
import router from '@ohos.router';
@Entry
@Component
struct RouterDemo{
build(){
Column({space:20}){
//跳转到注册页面
Text('没有账号,立即注册')
.fontSize(22)
.fontColor(0x1677ff)
.onClick(()=>{
router.pushUrl({
url:"pages/Resister"
})
})
//跳转到登陆页面
Text('已有账号,立即登录')
.fontSize(22)
.fontColor(0x1655dd)
.onClick(()=>{
router.pushUrl({
url:"pages/LoginPage"
})
})
}.width('100%')
.height('100%')
.padding(12)
}
}
1.2 极简注册页 Resister.ets(无任何交互)
仅展示文字,无返回、无输入框,用来验证跳转是否成功
@Entry
@Component
struct Resister{
build() {
Column(){
Text("你好,这是一个注册页面!")
.fontSize(25)
.fontColor(0x77d441)
}
.width("100%")
.height("100%")
}
}
阶段 1 核心知识点
import router from '@ohos.router':所有路由操作必须导入;router.pushUrl({url:"页面路径"}):打开新页面,页面入栈,系统返回键可以回到上一页;- url 路径必须和
main_pages.json注册名称完全一致,区分大小写。
第二阶段:进阶路由(增加基础表单、页面互相跳转)
在阶段 1 基础上,给登录页面增加账号密码输入框,同时增加页面互跳逻辑(登录页可以点击文字跳注册页)
2.1 LoginPage.ets 简易登录表单页
新增 Image 头像、账号 / 密码输入框、页面互跳文字按钮
import router from '@ohos.router';
@Entry
@Component
struct RouterLogin{
build() {
Column({space:25}){
// 顶部头像图片
Image($r('app.media.图片名称'))
.width(120)
.height(120)
.borderRadius(60)
Text("登 录")
.fontSize(32)
.fontWeight(FontWeight.Bold)
Row({space:15}){
Text("账 号")
.fontSize(26)
TextInput()
.width("70%")
.height(50)
}
Row({space:15}){
Text("密 码")
.fontSize(26)
TextInput()
.width("70%")
.height(50)
.type(InputType.Password)
}
Text("没有账号,立即注册")
.fontSize(22)
.fontColor(0xababab)
.onClick(()=>{
router.pushUrl({
url:"pages/RouterRegister"
})
})
Button("立 即 登 录")
.width('100%')
.height(50)
.fontSize(24)
}
.width('100%')
.height('100%')
.padding(15)
}
}
2.2 RouterLogin.ets 标准登录页(纯 UI,无逻辑)
和 LoginPage 结构一致,作为正式登录页面模板,仅 UI 展示,暂不做登录业务逻辑
import router from '@ohos.router';
@Entry
@Component
struct RouterRegister{
build() {
Column({space:25}){
Image($r('app.media.banner0'))
.width(120)
.height(120)
.borderRadius(60)
Text("登录")
.fontSize(32)
.fontWeight(FontWeight.Bolder)
Row(){
Text("账号")
.fontSize(26)
.width('40%')
.textAlign(TextAlign.Center)
TextInput()
.width('60%')
.height(50)
}
Row(){
Text("密码")
.fontSize(26)
.width('40%')
.textAlign(TextAlign.Center)
TextInput()
.width('60%')
.height(50)
.type(InputType.Password)
}
Text("没有账号,立即注册")
.fontSize(22)
.fontColor(0xababab)
.onClick(()=>{
router.pushUrl({
url:"pages/RouterRegister"
})
})
Button("登录")
.width('100%')
.height(50)
.fontSize(24)
}
.width('100%')
.height('100%')
.padding(15)
}
}
阶段 2 新增知识点
TextInput(type:InputType.Password):密码框隐藏输入内容;- 多页面循环跳转:登录页 ↔ 注册页互相导航,熟悉页面栈叠加逻辑;
- Image 资源使用:提前在 media 文件夹放置对应图片资源。
第三阶段:中级路由(双向数据绑定 + 表单校验)
新增完整注册页面RouterRegister.ets,使用@State实现输入框双向绑定,增加表单校验、弹窗提示
import router from '@ohos.router';
@Entry
@Component
struct RouterRegister{
@State username:string = ""
@State password:string = ""
@State password2:string = ""
build() {
Column({space:25}){
Image($r('app.media.banner0'))
.width(120)
.height(120)
.borderRadius(60)
Text("注册")
.fontSize(32)
.fontWeight(FontWeight.Bolder)
Row(){
Text("账号")
.fontSize(26)
.width('40%')
.textAlign(TextAlign.Center)
TextInput({text:this.username})
.width('60%')
.height(50)
.onChange((value:string)=> {
this.username = value
})
}
Row(){
Text("密码")
.fontSize(26)
.width('40%')
.textAlign(TextAlign.Center)
TextInput({text:this.password})
.width('60%')
.height(50)
.type(InputType.Password)
.onChange((value:string)=> {
this.password = value
})
}
Row(){
Text("确认密码")
.fontSize(26)
.width('40%')
.textAlign(TextAlign.Center)
TextInput({text:this.password2})
.width('60%')
.height(50)
.type(InputType.Password)
.onChange((value:string)=> {
this.password2 = value
})
}
Text("已有账号,立即登录")
.fontSize(22)
.fontColor(0xababab)
.onClick(()=>{
router.pushUrl({
url:"pages/RouterLogin"
})
})
Button("立即注册")
.width('100%')
.height(50)
.fontSize(24)
.onClick(()=>{
if ((this.username!="") && (this.password!="") && (this.password2!="") &&(this.password==this.password2)){
router.pushUrl({
url:"pages/RouterLogin",
params:{
username:this.username,
password:this.password
}
})
}
else {
AlertDialog.show({
title:"注册失败",
message:`注册的两次密码为空或者不一致,${this.username}`
})
}
})
}
.width('100%')
.height('100%')
.padding(15)
}
}
阶段 3 新增核心知识点
@State装饰器:实现 UI 输入框与变量双向绑定;onChange监听输入框变化,实时保存用户输入;params路由传参:跳转页面时携带自定义数据对象;AlertDialog.show弹窗提示,表单校验失败反馈;- 基础逻辑判断
if-else完成表单合规校验。
第四阶段:高阶路由(接收页面传递参数,完整业务闭环)
新增HomePage.ets用户主页,使用router.getParams()接收上一页传递的用户名,完成注册→登录→主页完整业务链路
import router from '@ohos.router';
@Entry
@Component
struct HomePage{
@State username:string = ""
onPageShow(): void {
const params = router.getParams() as Record<string,string>
if (params){
this.username = params.username
}
}
build() {
Column(){
Text('你好${this.username}')
}
}
}
阶段 4 新增知识点
- 页面生命周期
onPageShow:页面显示时执行,适合接收路由参数; router.getParams():获取上一个页面跳转时传递的 params 数据;- 类型断言
as Record<string,string>解决 TS 类型警告; - 完整业务闭环:注册填写信息 → 传参到登录页 → 登录跳转主页展示用户名称。
整体学习顺序 & 运行流程
- 先运行阶段 1:掌握最基础页面跳转,确认路由配置无报错;
- 再运行阶段 2:学会表单 UI、页面互相跳转;
- 接着阶段 3:学习双向绑定、表单校验、路由传参;
- 最后阶段 4:掌握参数接收,打通完整登录注册业务。
开发避坑总结(按学习阶段对应)
- 阶段 1 踩坑:页面找不到 检查
main_pages.json是否注册页面,url 路径大小写、拼写必须完全匹配。 - 阶段 2 踩坑:图片资源报错 media 文件夹必须存在同名图片
banner0,资源名称不能包含中文、空格。 - 阶段 3 踩坑:输入框内容不更新 必须给
TextInput绑定text参数 +onChange同步 @State 变量,缺一不可。 - 阶段 4 踩坑:接收不到 params 参数 获取参数代码写在
onPageShow/aboutToAppear生命周期,不要写在 build 渲染函数中,同时增加 params 非空判断。
拓展优化建议(学完全部阶段后练习)
- 登录按钮增加跳转主页逻辑,使用
router.replaceUrl替换页面,避免页面栈堆积; - 封装路由工具类,统一管理页面路径常量,消除硬编码 url;
- 增加路由拦截:未登录时强制跳登录页;
- 完善表单校验:账号密码长度限制、特殊字符过滤;
- 登录成功添加 Toast 弹窗提示,优化用户交互体验。
更多推荐


所有评论(0)