本文将以APP的登录和修改昵称为例演示官网的几种页面跳转、返回以及这些流程携带参数,实例的形式记录学习HarmonyOS的页面跳转。
“页面路由指在应用程序中实现不同页面之间的跳转和数据传递。HarmonyOS提供了Router模块,通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。本文将从页面跳转、页面返回和页面返回前增加一个询问框几个方面介绍Router模块提供的功能。”这是官网对Router的介绍。
该案例非常简单我准备了LoginPages.ets、MainPages.ets、DetailPages.ets,分别是APP的登录页面、主页面和昵称修改页面。
登录页-LoginPage
首页-MainPage
详情页修改昵称-DetailPage
LoginPages.ets有一个登录按钮、和账号文本。
@State name: string = '张一三'
@State userId: string = '123456'
build() {
Row() {
Column() {
Text(this.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
Button("登录")
.fontSize(26)
.margin({
top:30
})
.padding({
left:30,
top:10,
right:30,
bottom:10,
})
.onClick(event =>{
//这里是放置具体的场景一、二、三、四、五的代码
})
场景一:初学HarmonyOS不管三七二十一我就想看一眼鸿蒙的页面跳转
router.pushUrl({
url: 'pages/MainPage' // 目标url
}, router.RouterMode.Standard, (err) => {
if (err) {
console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke pushUrl succeeded.');
});
有个小问题,如果我多次点击登录按钮会出现多个首页,这也不是我们想要的,于是场景二来了。
场景二:希望如果用户故意或者不小心点了多次登录按钮,保证每次只有一个首页存在于页面栈中,在返回时直接回到之前的登录页。这种场景下,可以使用pushUrl()方法,并且使用Single实例模式。 防止重复点击。
router.pushUrl({
url: 'pages/MainPage' // 目标url
}, router.RouterMode.Single, (err) => {
if (err) {
console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke pushUrl succeeded.');
});
不对啊,我从登录页点登录按钮成功后进入了进入App首页,怎么按返回键还能回到登录页,这肯定不对,需要优化。于是就有了下面的场景三。
场景三:希望从登录页成功登录后,跳转到首页。同时,销毁登录页,在返回时直接退出应用而不是回到登录页面。这种场景下,可以使用replaceUrl()方法,并且使用Standard实例模式。
router.replaceUrl({
url: 'pages/MainPage' // 目标url
}, router.RouterMode.Standard, (err) => {
if (err) {
console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke replaceUrl succeeded.');
})
场景四:主页面有一个“修改昵称”点击会跳转到DetailPages页面,如果DetailPages已经被查看过,则不需要再新建一个详情页,而是直接跳转到已经存在的详情页。这种场景下,可以使用replaceUrl()方法,并且使用Single实例模式。 place的防止重复点击,复用页面
router.replaceUrl({
url: 'pages/MainPage' // 目标url
}, router.RouterMode.Single, (err) => {
if (err) {
console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke replaceUrl succeeded.');})
上面场景都有一个特点是页面跳转时没有携带参数,但实际开发时在登录页与服务端交互后,服务端返回的一些参数和凭证是需要送给主页面的。
如果需要在跳转时传递一些数据给目标页,则可以在调用Router模块的方法时,添加一个params属性,并指定一个对象作为参数。例如:
let paramsInfo: DataModel = {
name: this.name,
userId: this.userId
};
router.pushUrl({
url: 'pages/MainPage', // 目标url
params: paramsInfo // 添加params属性,传递自定义参数
}, (err) => {
if (err) {
console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke pushUrl succeeded.');
})
这是定义传递的对象:
class DataModel {
name: string;
userId: string;
}
在目标页中,可以通过调用Router模块的getParams()方法来获取传递过来的参数。本案例在MainPages页面的aboutToAppear生命周期:
aboutToAppear(){
const params = router.getParams(); // 获取传递过来的参数对象
this.name = params['name']; // 获取id属性的值
const password = params['password'].age; // 获取age属性的值
console.log(" name= "+this.name+" password= "+password)
}
登陆后app首页就会显示登录页输入的账号。
- 页面返回
首页有一个修改昵称的按钮,点击会会到DetailPage页面,当用户完成操作后,需要将修改后的昵称返回到上一个页面或者指定页面,这就需要用到页面返回功能。在返回的过程中,可能需要将数据传递给目标页,这就需要用到数据传递功能。
可以使用以下几种方式进行页面返回:
Button("返回")
.fontSize(26)
.margin({
top:30
})
.padding({
left:30,
top:10,
right:30,
bottom:10,
}) .onClick(event =>{
//回到上一个页面
// router.back();
//回到指定页面
router.back({
url: 'pages/MainPage’
});
})
但是有一点必须注意,方式一的“上一个页面”或者方式二“我们指定的页面”,此处统称为返回的目标页面哈,返回的目标页面必须存在于页面栈中才能够返回,否则该方法将无效。
方式三:返回到指定页面,并传递自定义参数信息,此处我将修改后的昵称老梁学HarmonyOS
传回去了。
Button("确认修改")
.fontSize(26)
.margin({
top:30
})
.padding({
left:30,
top:10,
right:30,
bottom:10,
}) .onClick(event =>{
router.back({
url: 'pages/MainPage',
params: {
name: this.message
}
});
})
这种方式不仅可以返回到指定页面,还可以在返回的同时传递自定义参数信息。这些参数信息可以在目标页中通过调用router.getParams()方法进行获取和解析。我们在MainPage的在onPageShow()生命周期回调中:
onPageShow() {
const params = router.getParams(); // 获取传递过来的参数对象
const name = params['name']; // 获取info属性的值
this.name = name
}
首页-MainPage修改昵称以后
补充说明
1、鸿蒙提供了router.pushUrl()和router.replaceUrl()这两种跳转模式,很明显两者区别是目标页是否会替换当前页,即A面启动了B页面之后A页面是在B页面下面继续存活还是被直接销毁。
router.pushUrl():目标页不会替换当前页,而是压入页面栈。这样可以保留当前页的状态,并且可 以通过返回键或者调用router.back()方法返回到当前页。
router.replaceUrl():目标页会替换当前页,并销毁当前页。这样可以释放当前页的资源,并且无法返回到当前页。
2、页面栈的最大容量为32个页面。如果超过这个限制,可以调用router.clear()方法清空历史页面栈,释放内存空间。
3、标准实例模式下,router.RouterMode.Standard参数可以省略。
4、在使用页面路由Router相关功能之前,需要在代码中先导入Router模块。
import router from '@ohos.router'; 快捷键alt+enter是可以直接导包的