页面路由指在应用程序中实现不同页面之间的跳转和数据传递。
HarmonyOS提供了Router模块,通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。
包的使用及引用
import router from '@ohos.router'
1.pushUrl-压栈跳转
pushUrl(options: RouterOptions): Promise<void>
场景: 如果我们从列表页跳转到详情页查看详情,点击返回还要继续查看列表页,可以使用pushUrl,打开详情页的同时,保留了列表页在栈中。
接下来测试一下:
(1)建立两个Page,HmList和HmDetail,如图所示。
(2)实现HmList的布局,代码如下。
classListItemInfo{
title:string=""
id:number=0
}
@Entry
@Component
structHmList{
@Statelist:ListItemInfo[]=Array.from(Array(100),(_:number,index:number)=>{
return{
title:`我是第${index + 1}个`,
id:index+1
}asListItemInfo
})
build(){
Column({space:20}){
Row(){
Text("列表数据")
.textAlign(TextAlign.Center)
.width('100%')
.height(40)
}.border({
color:'#f3f4f5',
width:{
bottom:1
}
})
List({space:10}){
ForEach(this.list,(item:ListItemInfo)=>{
ListItem(){
Row(){
Text(item.title)
Button("查看详情")
.height(30)
}.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
left:10,
right:10
})
}
})
}
}
}
}
实现效果,如图所示。
(3)实现HmDetail布局,代码如下:
@Entry
@Component
structHmDetail{
build(){
Column(){
Row(){
Text("详情页")
.width('100%')
.textAlign(TextAlign.Center)
}.height(40)
.border({
color:'#f3f4f5',
width:{
bottom:1
}
})
Column(){
Text("详情页")
.fontSize(50)
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
}
.height('100%')
}
}
实现效果,如图所示。
(4)在HmList中导入router包,完成路由跳转
importrouterfrom'@ohos.router'
Button("查看详情").onClick(() => {
router.pushUrl({ url: 'pages/HmDetail' })
})
完整代码如下:
importrouterfrom'@ohos.router'
classListItemInfo{
title:string=""
id:number=0
}
@Entry
@Component
structHmList{
@Statelist:ListItemInfo[]=Array.from(Array(100),(_:number,index:number)=>{
return{
title:`我是第${index + 1}个`,
id:index+1
}asListItemInfo
})
build(){
Column({space:20}){
Row(){
Text("列表数据")
.textAlign(TextAlign.Center)
.width('100%')
.height(40)
}.border({
color:'#f3f4f5',
width:{
bottom:1
}
})
List({space:10}){
ForEach(this.list,(item:ListItemInfo)=>{
ListItem(){
Row(){
Text(item.title)
Button("查看详情").onClick(()=>{
router.pushUrl({url:'pages/HmDetail'})
})
.height(30)
}.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
left:10,
right:10
})
}
})
}
}
}
}
2.replaceUrl-替换跳转
有一个登录页(Login)和一个个人中心页(Profile),希望从登录页成功登录后,跳转到个人中心页。同时,销毁登录页,在返回时直接退出应用。
此时直接replaceUrl方法会在跳转的同时,销毁登录页,在上面的例子中,直接将pushUrl换成replaceUrl即可。
import router from '@ohos.router';
Button("查看详情").onClick(() => {
router.replaceUrl({ url: 'pages/HmDetail' })
})
})
总结
(1)当你需要跳转之后,还可以回到上一个页面,使用pushUrl,它会保留当前的页面,压一个新的页面
(2)当你跳转之后,上一个页面的任务已经完成,不需要返回,就可以使用replaceUrl
3.back返回
router.back() . 返回上一个页面,此时不需要参数,如果说你想要返回的时候带一些参数,需要params和url- 想要指定url.
(1)router.back()
在详情页加一个返回按钮,点击按钮调用router.back()。
importrouterfrom'@ohos.router'
Button("返回列表页")
.onClick(() => {
router.back()
})
添加一个返回按钮,完整代码如下:
importrouterfrom'@ohos.router'
@Entry
@Component
structHmDetail{
build(){
Column(){
Row(){
Text("详情页")
.width('100%')
.textAlign(TextAlign.Center)
}.height(40)
.border({
color:'#f3f4f5',
width:{
bottom:1
}
})
Column(){
Text("详情页")
.fontSize(50)
Button("返回列表页")
.onClick(()=>{
router.back()
})
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
}
.height('100%')
}
}
实现效果,如图所示。
4.路由参数
如果需要在跳转时,传递一些数据给目标页,比如列表页到详情页,想把id传过去,就可以使用路由传参的模式。
(1)修改HmList.ets文件,代码如下:
Button("查看详情").onClick(()=>{
router.pushUrl({
url:'pages/HmDetail',
params:{
id:item.id
}
})
})
(2)修改HmDetail.ets文件,子组件接收参数,代码如下:
importrouterfrom'@ohos.router'
classRouterParams{
id:number=0
}
@Entry
@Component
structHmDetail{
@State
detailId:number=0
aboutToAppear(){
constparams=router.getParams()asRouterParams
if(params?.id){
this.detailId=params?.id
}
}
build(){
Column(){
Row(){
Text("详情页")
.width('100%')
.textAlign(TextAlign.Center)
}.height(40)
.border({
color:'#f3f4f5',
width:{
bottom:1
}
})
Column(){
Text("详情页"+this.detailId)
.fontSize(50)
Button("返回列表页")
.onClick(()=>{
router.back()
})
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
}
.height('100%')
}
}
实现效果,如图所示。
router.back() 同样可以传递参数给上一级的路由,上一级路由应该在onPageShow里面接收详情页面返回传参。
(1)HmDetail.ets文件,详情组件添加“返回列表页带参数”按钮,代码如下:
Button("返回列表页带参数")
.onClick(() => {
router.back({
url: 'pages/HmList',
params: {
backId: this.detailId
}
})
})
(2)父组件接受参数,HmList.ets文件,代码如下:
class BackRouterParams {
backId: number = 0
}
onPageShow() {
const params = router.getParams() as BackRouterParams
if(params?.backId) {
AlertDialog.show({
message: params.backId.toString()
})
}
}
完整代码如下:
importrouterfrom'@ohos.router'
classListItemInfo{
title:string=""
id:number=0
}
classBackRouterParams{
backId:number=0
}
@Entry
@Component
structHmList{
@Statelist:ListItemInfo[]=Array.from(Array(100),(_:number,index:number)=>{
return{
title:`我是第${index + 1}个`,
id:index+1
}asListItemInfo
})
onPageShow(){
constparams=router.getParams()asBackRouterParams
if(params?.backId){
AlertDialog.show({
message:params.backId.toString()
})
}
}
build(){
Column({space:20}){
Row(){
Text("列表数据")
.textAlign(TextAlign.Center)
.width('100%')
.height(40)
}.border({
color:'#f3f4f5',
width:{
bottom:1
}
})
List({space:10}){
ForEach(this.list,(item:ListItemInfo)=>{
ListItem(){
Row(){
Text(item.title)
Button("查看详情").onClick(()=>{
// router.pushUrl({ url: 'pages/HmDetail' })
// router.replaceUrl({ url: 'pages/HmDetail' })
router.pushUrl({
url:'pages/HmDetail',
params:{
id:item.id
}
})
})
.height(30)
}.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
left:10,
right:10
})
}
})
}
}
}
}
实现效果,如图所示。
->
总结:
(1)传参用params对象,里面可以传任意内容,key/value由开发者自己定义。
(2)接收端采用router.getParams()获取对象,需要通过class来定义参数的结构,接收之后通过类型断言as指定为具体类型。
(3)如果是通过pushUrl的方式跳转的,返回上一个页面时,aboutToAppear不会执行,需要使用onPageShow来监听当前页面的显示钩子函数。
5.路由模式
Standard:标准实例模式,也是默认情况下的实例模式。每次调用该方法都会新建一个目标页,并压入栈顶。
Single:单实例模式。即如果目标页的url在页面栈中已经存在同url页面,则离栈顶最近的同url页面会被移动到栈顶,并重新加载;如果目标页的url在页面栈中不存在同url页面,则按照标准模式跳转。
简单理解一下就是:
(1)Standard-只要push,页面栈里面就会加一项,不管之前加没加过。
(2)Single- 之前加过,不会加新的页面,会把之前加过的页面加出来。
测试- 在detail页面再push到list页,分别使用单例模式和标准模式测试。
Button("标准模式")
.onClick(() => {
router.pushUrl({
url: 'pages/HmList'
})
})
Button("单例模式")
.onClick(() => {
router.pushUrl({
url: 'pages/HmList'
}, router.RouterMode.Single)
})
这里会发现 使用single模式路由返回时的list已经不存在了,因为单例模式只要存在不会再压栈。
HmDetail.ets文件,完整代码如下:
importrouterfrom'@ohos.router'
classRouterParams{
id:number=0
}
@Entry
@Component
structHmDetail{
@State
detailId:number=0
aboutToAppear(){
constparams=router.getParams()asRouterParams
if(params?.id){
this.detailId=params?.id
}
}
build(){
Column(){
Row(){
Text("详情页")
.width('100%')
.textAlign(TextAlign.Center)
}.height(40)
.border({
color:'#f3f4f5',
width:{
bottom:1
}
})
Column(){
Text("详情页"+this.detailId)
.fontSize(50)
Button("返回列表页")
.onClick(()=>{
router.back()
})
Button("返回列表页带参数")
.onClick(()=>{
router.back({
url:'pages/HmList',
params:{
backId:this.detailId
}
})
})
Button("标准模式")
.onClick(()=>{
router.pushUrl({
url:'pages/HmList'
})
})
Button("单例模式")
.onClick(()=>{
router.pushUrl({
url:'pages/HmList'
},router.RouterMode.Single)
})
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
}
.height('100%')
}
}
实现效果,如图所示。
欢迎加入课程班级,考取鸿蒙认证:
https://developer.huawei.com/consumer/cn/training/classDetail/d43582bb30b34f548c16c127cb3be104?type=1?ha_source=hmosclass&ha_sourceId=89000248