HarmonyOS Router

页面路由(router)

  • 页面路由指在应用程序中实现不同页面之间的跳转和数据传递。HarmonyOS提供了Router模块,通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。

一、页面跳转

1. Router模块提供了两种跳转模式, 分别是router.pushUrl()router.replaceUrl()。这两种模式决定了目标页是否会替换当前页。

  1. router.pushUrl()
    :目标页不会替换当前页,而是压入页面栈。这样可以保留当前页的状态,并且可以通过返回键或者调用router.back()方法返回到当前页。
  2. router.replaceUrl():目标页会替换当前页,并销毁当前页。这样可以释放当前页的资源,并且无法返回到当前页。
  3. 页面栈的最大容量为32个页面。如果超过这个限制,可以调用router.clear()方法清空历史页面栈,释放内存空间。
  • 在使用页面路由Router相关功能之前,需要在代码中先导入Router模块。
  import router from '@ohos.router';

2. Router模块提供了两种实例模式,分别是StandardSingle。这两种模式决定了目标url是否会对应多个实例。

  1. Standard:标准实例模式,也是默认情况下的实例模式。每次调用该方法都会新建一个目标页,并压入栈顶。
    • 场景一:有一个主页(Home)和一个详情页(Detail),希望从主页点击一个商品,跳转到详情页。同时,需要保留主页在页面栈中,以便返回时恢复状态。这种场景下,可以使用pushUrl()
      方法,并且使用Standard实例模式(或者省略)。
      // 在Home页面中
      function onJumpClick(): void {
         router.pushUrl({
           url: 'pages/Detail' // 目标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.');
         });
      }
    
  • 场景二:有一个登录页(Login)和一个个人中心页(Profile),希望从登录页成功登录后,跳转到个人中心页。同时,销毁登录页,在返回时直接退出应用。这种场景下,可以使用replaceUrl()
    方法,并且使用Standard实例模式(或者省略)。
    // 在Login页面中
    function onJumpClick(): void {
     router.replaceUrl({
       url: 'pages/Profile' // 目标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.');
     })
    }
    
  1. Single:单实例模式。即如果目标页的url在页面栈中已经存在同url页面,则离栈顶最近的同url页面会被移动到栈顶,并重新加载;如果目标页的url在页面栈中不存在同url页面,则按照标准模式跳转。
    • 场景一:有一个设置页(Setting)和一个主题切换页(Theme),希望从设置页点击主题选项,跳转到主题切换页。同时,需要保证每次只有一个主题切换页存在于页面栈中,在返回时直接回到设置页。这种场景下,可以使用pushUrl()
      方法,并且使用Single实例模式。
    // 在Setting页面中
    function onJumpClick(): void {
      router.pushUrl({
        url: 'pages/Theme' // 目标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.');
      });
    }
    
    • 场景二:有一个搜索结果列表页(SearchResult)和一个搜索结果详情页(SearchDetail),希望从搜索结果列表页点击某一项结果,跳转到搜索结果详情页。同时,如果该结果已经被查看过,则不需要再新建一个详情页,而是直接跳转到已经存在的详情页。这种场景下,可以使用replaceUrl()
      方法,并且使用Single实例模式。
     // 在SearchResult页面中
     function onJumpClick(): void {
       router.replaceUrl({
         url: 'pages/SearchDetail' // 目标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.');
       })
     }
    
  2. 带参数页面跳转
  • 需要在跳转时传递一些数据给目标页,则可以在调用Router模块的方法时,添加一个params属性,并指定一个对象作为参数
class DataModelInfo {
  age: number;
}

class DataModel {
  id: number;
  info: DataModelInfo;
}

function onJumpClick(): void {
  // 在Home页面中
  let paramsInfo: DataModel = {
    id: 123,
    info: {
      age: 20
    }
  };
        
  router.pushUrl({
    url: 'pages/Detail', // 目标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.');
  })
}
  • 在目标页中,可以通过调用Router模块的getParams()方法来获取传递过来的参数。
const params = router.getParams(); // 获取传递过来的参数对象
const id = params['id']; // 获取id属性的值
const age = params['info'].age; // 获取age属性的值

二、页面返回

  • 在使用页面路由Router相关功能之前,需要在代码中先导入Router模块。
import router from '@ohos.router';

1. 方式一:返回到上一个页面。

  • 这种方式会返回到上一个页面,即上一个页面在页面栈中的位置。但是,上一个页面必须存在于页面栈中才能够返回,否则该方法将无效。
     router.back();
    

2. 方式二:返回到指定页面。

  • 这种方式可以返回到指定页面,需要指定目标页的路径。目标页必须存在于页面栈中才能够返回。
    router.back({
      url: 'pages/Home',
      params: {
        info: '来自Home页'
      }
    });
    

3. 方式三:返回到指定页面,并传递自定义参数信息。

  • 这种方式不仅可以返回到指定页面,还可以在返回的同时传递自定义参数信息。这些参数信息可以在目标页中通过调用router.getParams()
    方法进行获取和解析。
router.back({
  url: 'pages/Home',
  params: {
    info: '来自Home页'
  }
});
  • 在需要获取参数的位置调用router.getParams()方法即可,例如在onPageShow()生命周期回调中:
onPageShow() {
const params = router.getParams(); // 获取传递过来的参数对象
const info = params['info']; // 获取info属性的值
}

三、页面返回前增加一个询问框

1. 系统默认询问框

  • 为了实现这个功能,可以使用页面路由Router模块提供的两个方法:router.showAlertBeforeBackPage()router.back()来实现这个功能。
  1. 在使用页面路由Router相关功能之前,需要在代码中先导入Router模块。\

    import router from '@ohos.router';
    
  2. 如果想要在目标界面开启页面返回询问框,需要在调用router.back()方法之前,通过调用router.showAlertBeforeBackPage()
    方法设置返回询问框的信息。例如,在支付页面中定义一个返回按钮的点击事件处理函数:

// 定义一个返回按钮的点击事件处理函数
function onBackClick(): void {
  // 调用router.showAlertBeforeBackPage()方法,设置返回询问框的信息
  try {
    router.showAlertBeforeBackPage({
      message: '您还没有完成支付,确定要返回吗?' // 设置询问框的内容
    });
  } catch (err) {
    console.error(`Invoke showAlertBeforeBackPage failed, code is ${err.code}, message is ${err.message}`);
  }

  // 调用router.back()方法,返回上一个页面
  router.back();
}

其中,router.showAlertBeforeBackPage()方法接收一个对象作为参数,该对象包含以下属性:

  • message:string类型,表示询问框的内容。
    如果调用成功,则会在目标界面开启页面返回询问框;如果调用失败,则会抛出异常,并通过err.codeerr.message获取错误码和错误信息。

当用户点击“返回”按钮时,会弹出确认对话框,询问用户是否确认返回。选择“取消”将停留在当前页目标页;选择“确认”将触发router.back()
方法,并根据参数决定如何执行跳转。

2. 自定义询问框

  • 在使用页面路由Router相关功能之前,需要在代码中先导入Router模块。
import router from '@ohos.router';
  • 在事件回调中,调用弹窗的promptAction.showDialog()方法:
function onBackClick() {
  // 弹出自定义的询问框
  promptAction.showDialog({
    message: '您还没有完成支付,确定要返回吗?',
    buttons: [
      {
        text: '取消',
        color: '#FF0000'
      },
      {
        text: '确认',
        color: '#0099FF'
      }
    ]
  }).then((result) => {
    if (result.index == 0) {
      // 用户点击了“取消”按钮
      console.info('User canceled the operation.');
    } else if (result.index == 1) {
      // 用户点击了“确认”按钮
      console.info('User confirmed the operation.');
      // 调用router.back()方法,返回上一个页面
      router.back();
    }
  }).catch((err) => {
    console.error(`Invoke showDialog failed, code is ${err.code}, message is ${err.message}`);
  })
}
  • 当用户点击“返回”按钮时,会弹出自定义的询问框,询问用户是否确认返回。选择“取消”将停留在当前页目标页;选择“确认”将触发router.back()方法,并根据参数决定如何执行跳转。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • JSV5 1、vue 双向绑定的原理 通过object.defineProperty()方法来劫持属性的gette...
    merlinxu阅读 1,134评论 0 1
  • UIAbility: 单UIAbility,多UIAbility。 UIAbility 是一种包含用户界面的应用组...
    xqiiitan阅读 100评论 0 1
  • vue中Axios的封装和API接口的管理 我们所要的说的axios的封装和api接口的统一管理,其实主要目的就是...
    我王某不需要昵称阅读 666评论 0 2
  • 在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在...
    lan1997阅读 1,358评论 0 1
  • vue中Axios的封装和API接口的管理 我们所要的说的axios的封装和api接口的统一管理,其实主要目的就是...
    古月梦回阅读 1,320评论 0 0