鸿蒙-08(路由通信)

17 阅读3分钟

方式一(官方推荐)

Navigation:这种方案是目前官方推荐我们使用,但是这种方案涵盖的内容比较多。底部tabbar,顶部菜单, 返回等等。集合了页面中各种跳转、返回、菜单等功能。

方式二

router路由:router路由类似于以前vue或者react框架中提供的路由对象。在代码中调用他的api来实现路由的跳转、返回、参数的传递。

router路由跳转:

  1. pushUrl:代表跳转页面的时候,将老的地址和新的地址都加入到页面执行栈。可以实现跳转过后记录信息,可 以返回到指定的页面。
  2. replaceUrl:代表替换当前这个页面的地址。直接覆盖我们访问地址。无法记录历史。无法返回跳转之前

router的模式:

  1. Standard:多实例模式,按pushUrl来跳转,每次跳转路径都会放在执行栈中,不会去管执行栈中是否存在同样的路由路径。
  2. single:单实例模式,按pushUrl来跳转,每次跳转的路径都会放在执行栈,如果下次访问同一个路径,默认将执行栈中存在的路径放在栈顶。执行栈中同样的路径只会存在一次

跳转API

导入模块

import { router } from '@kit.ArkUI';

调用

 router.pushUrl({
  url: 'pages/routerpage2',
  params: new routerParams('message', [123, 456, 789])
 })
 // 或
 router.replaceUrl({
  url: 'pages/routerpage2',
  params: new routerParams('message', [123, 456, 789])
 })

完整用法

router.pushUrl({
  url: 'pages/routerpage2',
  params: new routerParams('message', [123, 456, 789])
}, router.RouterMode.Standard)
  .then(() => {
      console.error(`pushUrl finish`);
  })
  .catch((err: ESObject) => {
      console.error(`pushUrl failed, code is ${(err as BusinessError).code}, message is ${(err as BusinessError).message}`);
 })
 
 // or
 
 router.pushUrl({
  url: 'pages/routerpage2',
  params: new routerParams('message', [123, 456, 789])
 }, router.RouterMode.Standard, (err) => {
  if (err) {
      console.error(`pushUrl failed, code is ${err.code}, message is ${err.message}`);
      return;
  }
  console.info('pushUrl success');
 })

总结:

  1. 路由跳转过程中,可以只传递第一个参数。里面包含跳转的地址和传递参数。
  2. 路由跳转过程中,第二个参数可以省略,也可以加上。不写默认就是Standard模式。
  3. 参数三代表跳转结果。err值决定了是否有错误。

参数传递

params就是路由传递参数的时候,默认属性。内容默认为object,所以你可有传递任何结果

router.pushUrl({
  url: 'pages/Page06_state',
  params:{value:{id:1}}
})

参数接收

获取到参数也默认为object

import {router} from "@kit.ArkUI"
@Entry
@Component
struct Page {
  // 组件加载完毕后执行
  aboutToAppear(): void {
    // 获取到路由传递过来参数params获取到结果,默认类型object
    let params=router.getParams()
    // params 不做类型约束语法检查会报错,因无法确认router.getParams会得到什么样的对象数据
    let result=params.value
  }

类型约束的越精准,代码推断的就越精准

未约束

获取到的params变量默认为object类型。后续在使用的时候出现类型无法明确,进行报错

image.png 为了参数传递通用,需要写一个公共方法

// src/main/ets/viewModel/TaskParamsModel.ets
// 约束路由传参的数据格式 使用泛型
export class ParamsType<T> {
  value:T
  constructor(value:T) {
    this.value=value
  }
}

类型断言:我告诉编辑器,我比你更明白我的代码数据类型。不用自己去推断类型。

我比你更清楚我自己想要的数据类型是什么,告诉我们编辑器,我明确知道params对象数据类型为ParansType

image.png

因ParamsType中value是泛型,还需要指定类型

image.png

enum TaskStatusType {
  DONE = "done",
  UNDONE = "undone",
  FUTURE = "future",
  DOING = "doing"
}
// 定义数据约束
export class TaskModel {
  id:string = ""
  taskName:string = ""
  taskTime:string = ""
  taskMsg:string =""
  taskBeginDate:string = ""
  taskEndDate:string = ""
  // 任务类型,1:生活类型 2:工作类型
  taskType:number = 1
  taskTitle:number =1
  // 任务状态: done完成 undone未完成 doing正在进行 future未来任务
  taskStatus:string = ""
  constructor(id:string,taskName:string,taskTime:string,taskMsg:string,taskBeginDate:string,taskEndDate:string,taskType:number,taskTitle:number) {
    this.id=id
    this.taskName = taskName
    this.taskTime = taskTime
    this.taskMsg=taskMsg
    this.taskBeginDate = taskBeginDate
    this.taskEndDate = taskEndDate
    // 任务类型,1:生活类型 2:工作类型
    this.taskType = taskType
    this.taskTitle = taskTitle
    // 任务状态不用传递,由计算得出
    this.updateTaskStatus()
  }
  // 用于根据当前任务时间,计算任务状态
  updateTaskStatus(){
    const currentDate=formatDate(new Date().getTime(),"yyyy-mm-dd");
    if(this.taskTime>currentDate){
      this.taskStatus=TaskStatusType.FUTURE;
    }
    if(this.taskTime === currentDate){
      this.taskStatus=TaskStatusType.DOING;
    }
    if(this.taskTime <= currentDate){
      this.taskStatus = TaskStatusType.UNDONE
    }
  }
}