首页 > 其他分享 >【最新鸿蒙应用开发】——Router页面路由

【最新鸿蒙应用开发】——Router页面路由

时间:2024-07-10 11:56:11浏览次数:11  
标签:鸿蒙 url 100% router 跳转 pushUrl Router 路由 页面

Router路由

页面路由指的是在应用程序中实现不同页面之间的跳转,以及数据传递。通过 Router 模块就可以实现这个功能.

img

1. 创建页面

之前是创建的文件,使用路由的时候需要创建页面,步骤略有不同

  1. 方法 1:直接右键新建Page(常用)

  2. 方法 2:单独添加页面并配置

1.1. 直接右键新建Page

创建的是页面,选项不要选错了

1.2. 单独添加页面并配置

也可以单独创建文件,然后设置为页面

  • 新建页面
pages/DetailPage.ets

@Entry
@Component
struct DetailPage {
  build() {
    Column({ space: 15 }) {
      Text('Detail Page')
        .fontSize(40)
      Button('Back')
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}
  •  调整配置

小技巧:

  • 按两次 shift 在弹出的界面中输入文件名,可以快速定位

{
  "src": [
    "pages/Index",
+    "pages/DetailPage"
  ]
}

TIP

  • 手动新建一个页面(ets)文件,需要在 main_pages.json 中手动配置

  • 可以自动创建(会自动添加配置)

  • 删除页面**不会自动删除配置,需要手动删除**

2. 页面跳转

接下来学习路由的跳转,页面跳转是开发过程中的一个重要组成部分。

在使用应用程序时,通常需要在不同的页面之间跳转,有时还需要将数据从一个页面传递到另一个页面。接下来咱们分场景来讲解这部分的内容:

  1. 页面跳转与后退

  2. 路由模式

  3. 参数传递

2.1. 页面跳转与后退

首先来看看看使用频率最高的 跳转和 后退,核心就是使用 router 的方法

// 1. 导入
import router from '@ohos.router';
​
// 2.调用方法-普通跳转(可以返回)
router.pushUrl({
  url:'页面地址'
})
​
// 2.调用方法-替换跳转(无法返回)
router.replaceUrl({
  url:'页面地址'
})
​
// 2.调用方法-返回()
router.back()

  1. 创建目录,管理页面:

  2. 在目录下添加:首页,详情页
  3. 页面 A 中分别使用pushUrl和replaceUrl跳转到页面 B

  4. 页面 B 测试 back 方法返回

import router from '@ohos.router'
​
@Entry
  @Component
  struct Index {
    build() {
      Column({ space: 15 }) {
        Text('首页')
          .fontSize(40)
​
        // 通过 router 模块进行跳转
        Button('去详情页-pushUrl')
          .onClick(() => {
            router.pushUrl({
              url: 'pages/day11/knowledges/router01/DetailPage',
            })
          })
        Button('去详情页-replaceUrl')
          .onClick(() => {
            router.replaceUrl({
              url: 'pages/day11/knowledges/router01/DetailPage',
            })
          })
      }
      .height('100%')
        .width('100%')
        .justifyContent(FlexAlign.Center)
​
    }
  }
import router from '@ohos.router'
​
@Entry
  @Component
  struct DetailPage {
    build() {
      Row() {
        Column() {
          Text('详情页')
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
          Button('返回')
            .onClick(() => {
              router.back()
            })
        }
        .width('100%')
      }
      .height('100%')
    }
  }

router.pushUrl() 和 router.replaceUrl()。都可以跳转页面,区别为是否会替换当前页。

  • router.pushUrl():目标页面不会替换当前页,而是压入页面栈。这样可以保留当前页的状态,并且可以通过返回键或者调用router.back()方法返回到当前页。

  • router.replaceUrl():目标页面会替换当前页,并销毁当前页。这样可以释放当前页的资源,并且无法返回到当前页。

划重点:pushUrl 可以返回 replaceUrl 无法返回

2.2. 页面栈

页面栈是用来存储程序运行时页面的一种数据结构,遵循先进后出的原则,咱们结合刚刚的代码来说明一下:

页面栈的最大容量为32个页面

2.2.1. pushUrl的情况

先来看看 pushUrl的情况

  1. 默认打开首页 → 首页入栈

  2. pushUrl 去详情页 → 详情页入栈

  3. back 返回上一页 → 详情页出栈

  4. 此时页面栈中应该只有一个页面

整一个过程中,都可以 router.getLength 进行查看

img

2.2.2. replaceUrl 的情况

再来看看replaceUrl的情况

  1. 默认打开首页 → 首页入栈

  2. replaceUrl 去详情页 → 详情页替换首页,首页销毁

  3. back 无法返回 → 没有上一页

img

2.2.3. 页面栈相关 api

为了让咱们更好的获取页面栈的信息,router 模块也提供了对应的 api 以供使用

// 获取页面栈长度
router.getLength()
​
// 获取页面状态 
let page = router.getState();
console.log('current index = ' + page.index);
console.log('current name = ' + page.name);
console.log('current path = ' + page.path);
​
// 清空页面栈
router.clear()

3. 路由模式

路由提供了两种不同的跳转模式,不同模式的决定了页面是否会创建多个实例

  • standard(标准实例模式)是默认情况下的实例模式。在这种模式下,每次调用都会新建一个目标页,并压入页面栈顶。这意味着无论之前是否添加过相同的页面,每次跳转都会创建一个新的页面实例。这种模式的优点是可以确保每次跳转都是全新的页面状态,不会受到之前页面状态的影响。适用于那些需要每次跳转都呈现全新内容或状态的场景,或者需要避免复用已有页面实例导致的数据混淆问题。

  • Single(单实例模式)则会在页面栈中检查是否存在相同URL的页面。如果存在,离栈顶最近的同URL页面会被移动到栈顶,并重新加载;如果不存在,则按照标准模式跳转。这种模式的优势在于可以复用已有的页面实例,避免重复创建相同的页面,提高应用性能和资源利用率。它适用于那些需要保留页面状态或避免重复创建相同页面的场景,比如当用户在应用内多次访问同一页面时,使用Single模式可以确保页面的状态得到保持,并提供更加流畅的用户体验。

简而言之:

  1. Standard:无论之前是否添加过,一直添加到页面栈【常用】

  2. Single:如果之前加过页面,会使用之前添加的页面【看情况】

// 多实例模式下,router.RouterMode.Standard参数可以省略。
​
// pushUrl 和 replaceUrl 均可以在第二个参数设置 【路由模式】
router.pushUrl(options,mode)
router.replaceUrl(options,mode)

RouterMode参数说明

名称说明
Standard多实例模式,也是默认情况下的跳转模式。 目标页面会被添加到页面栈顶,无论栈中是否存在相同url的页面。 说明: 不使用路由跳转模式时,则按照默认的多实例模式进行跳转。
Single单实例模式。 如果目标页面的url已经存在于页面栈中,则该url页面移动到栈顶。 如果目标页面的url在页面栈中不存在同url页面,则按照默认的多实例模式进行跳转。

img

@Entry
@Component
struct HomePage {
  build() {
    Stack() {
      Image($r("app.media.douban_home"))
        .width('100%')
      Button('电影详情')
        .translate({ x: -120 })
        .onClick(() => {
​
        })
    }
    .height('100%')
  }
}
@Entry
@Component
struct MoviePage {
  @State message: string = 'Hello World';
​
  build() {
    Stack() {
      Image($r("app.media.douban_movie"))
        .width('100%')
      Button('演员')
        .translate({ x: -35, y: 180 })
        .onClick(() => {
​
        })
    }
    .height('100%')
  }
}
@Entry
@Component
struct ActorPage {
  build() {
    Stack() {
      Image($r("app.media.douban_actor"))
      Button('电影')
        .translate({ x: 43, y: 80 })
        .onClick(() => {
         
        })
    }
    .height('100%')
  }
}

3.1. Strandard模式

使用 Strandard 模式,在电影和演员页面反复跳转时会持续往页面栈中添加新的页面,浪费内存

img

3.2. Single模式

使用 Single 模式,在页面和演员页面反复跳转时会将已有的页面移到栈顶,避免浪费内存

img

4. 参数

接下来看看另外一个挺常见的需求:传递参数

日常开发中有这样的场景:点击不同的电影,商品,标题。。。跳转到与之对应的详情页面。

详情页面的布局是类似的,但是内容被替换为与之对应的内容。这就是一个常见的需要传递参数的场景:

列表 → 详情

img

4.1. 参数传递及接收

首先来看看如何实现页面参数传递和获取

// -----------传递参数------------
// 普通跳转 并 传递参数
router.pushUrl({
  url:'地址',
  params:{
    // 以对象的形式传递参数
  }
})
// 覆盖跳转并传递参数
router.replaceUrl(
  url:'地址',
  params:{
    // 以对象的形式传递参数
  }
)
// 返回并传递参数
router.back(
  url:'地址',
  params:{
    // 以对象的形式传递参数
  }
)
​
// -------------页面 B接收并解析参数------------
// aboutToAppear一会展开 (生命周期函数)
aboutToAppear(): void {
  // 1.确认内容
  console.log(JSON.stringify(router.getParams())) 
  // 2.通过 as 类型断言 转为具体的类型
  const params =  router.getParams() as 类型
  // 3. 通过点语法即可取值
  params.xxx 
} 

options参数说明

名称类型必填说明
urlstring表示目标页面的url,可以用以下两种格式: - 页面绝对路径,由配置文件中pages列表提供,例如: - pages/index/index - pages/detail/detail - 特殊值,如果url的值是"/",则跳转到首页。
paramsobject表示路由跳转时要同时传递到目标页面的数据,切换到其他页面时,当前接收的数据失效。跳转到目标页面后,使用router.getParams()获取传递的参数

img

  1. 创建目录管理页面

    1. 创建首页

    2. 创建详情页

  2. 【首页】携带数据去 【详情页】

  3. 【详情页】接收并解析数据

export class MovieInfo {
  id: number = 0
}
​
@Entry
@Component
struct Home {
  build() {
    Stack() {
      Image($r('app.media.douban_home'))
        .width('100%')
      Row({ space: 10 }) {
        Button('热辣滚烫')
          .onClick(() => {
            // id: 36081094 图片 params_movie1
​
          })
        Button('第二十条')
          .onClick(() => {
            // id: 36208094  图片 params_movie2
​
          })
        Button('飞驰人生')
          .onClick(() => {
            // id: 36369452  图片 params_movie3
​
          })
      }
      .translate({ x: -10 })
​
    }
    .height('100%')
  }
}
@Entry
@Component
struct Params {
  @State imgUrl: ResourceStr = $r('app.media.params_movie1');
​
  aboutToAppear(): void {
      // 根据 传递过来的 id 决定渲染不同的图片
      // 热辣滚烫 // id == 36081094
      // 第二十条 // id == 36208094
      // 飞驰人生 2 // id == 36369452
  }
​
  build() {
    Row() {
      Image(this.imgUrl)
    }
    .height('100%')
  }
}

5. 共享元素转场

当路由进行切换时,可以通过设置组件的 sharedTransition 属性将该元素标记为共享元素并设置对应的共享元素转场动效。

// 页面 A
组件(){
  
}
  .sharedTransition('标记', { duration: 500 })
​
// 页面 B
组件(){
  
}
  .sharedTransition('标记', { duration: 500 })

动画属性

名称参数类型是否必填参数描述
durationnumber描述共享元素转场动效播放时长。 默认值:1000。 单位:毫秒。
curveCurve | string | ICurve10+描述共享元素转场动效播放时长。 默认值:1000。 单位:毫秒。
delaynumber延迟播放时间。 默认值:0。 单位:毫秒。
motionPathMotionPathOptions运动路径信息。
zIndexnumber设置Z轴。
typeSharedTransitionEffectType动画类型。 默认值:SharedTransitionEffectType.Exchange。

效果

代码

Index.ets

import router from '@ohos.router'
​
export interface ProjectItem {
  id:number
  img: ResourceStr
  title: string
  desc: string
  sub: string
}
​
@Entry
@Component
struct Index {
  @State projectItem: ProjectItem[] = [
    {
      id:1,
      img: $r('app.media.project02'),
      title: '后台管理系统',
      desc: '以Vue技理后台后台管理系统面试题面试整理',
      sub: '后台系统'
    },
    {
      id:2,
      img: $r('app.media.project01'),
      title: '在线问医生平台(医疗类)',
      desc: '通过vue3+ts实现的在线医疗问诊相关技术整理',
      sub: 'H5项目'
    },
    {
      id:3,
      img: $r('app.media.project03'),
      title: '鸿蒙知识点',
      desc: '以ArkTS与ArkUI为主的鸿蒙基础知识点讲解',
      sub: '鸿蒙应用'
    },
  ]
​
  build() {
    Column() {
      Row() {
        Text('项目').fontSize(20)
      }
      Column() {
        ForEach(this.projectItem, (item: ProjectItem) => {
          Row({ space: 10 }) {
            Image(item.img).height('100%')
              .sharedTransition(item.id.toString(),{duration:500
              // ,type:SharedTransitionEffectType.Static
              })
            Column() {
              Column({ space: 5 }) {
                Text(item.title).fontSize(18)
                Text(item.desc).fontSize(12).fontColor('#666')
              }
              .alignItems(HorizontalAlign.Start)
​
              Text(item.sub).fontSize(10)
                .padding(3).fontColor(Color.Green)
                .backgroundColor('rgb(241, 244, 244)')
            }.height('100%')
            .alignItems(HorizontalAlign.Start)
            .justifyContent(FlexAlign.SpaceBetween)
          }.width('100%').height(110)
          .padding({ top: 15, bottom: 15 })
          .onClick(() => {
            router.pushUrl({
              url: "pages/DetailItem",
              params: item
            })
          })
        })
      }
    }.width('100%').height('100%').padding(15)
  }
}

DetailItem.ets

import router from '@ohos.router'
import { ProjectItem } from '../pages/Index'
​
@Entry
@Component
struct DetailPage {
  aboutToAppear(): void {
    const data = router.getParams() as ProjectItem
    this.data = data
  }
​
  @State data: ProjectItem = { id: 0 ,img: '', title: '', desc: '', sub: '' }
  @State isShow: boolean = true
​
  build() {
    Column() {
​
      Stack() {
        Column({ space: 30 }) {
          Row() {
            Text('<').fontColor('#fff').fontSize(30)
          }
          Row({ space: 10 }) {
            Image(this.data.img).height(150)
              .sharedTransition(this.data.id.toString(),{ duration:500
                // ,type:SharedTransitionEffectType.Static
              })
​
            Column() {
              Text(this.data.title).fontSize(20).fontColor('#fff')
              Text(this.data.desc).fontColor('#fff')
                .maxLines(2)
                .textOverflow({ overflow: TextOverflow.Ellipsis })
                .width('65%')
​
              Text(`学习进度:10%`).fontColor('#999')
            }
            .alignItems(HorizontalAlign.Start)
            .height(150).justifyContent(FlexAlign.SpaceAround)
          }
        }
        .padding(20)
        .alignItems(HorizontalAlign.Start)
​
        Image($r('app.media.project_bg'))
          .opacity(0.2).width('100%')
          .onClick(() => {
            router.back({
              url: "pages/Index"
            })
          })
      }
      .height('100%')
      .alignContent(Alignment.TopStart)
      .backgroundColor('#683a18')
      .bindSheet($$this.isShow, this.BindSheetContent(), {
        height: 520, showClose: false
      })
    }
  }
​
  @Builder
  BindSheetContent() {
    Row() {
      Text('问题列表').fontSize(25).fontWeight(500).margin(20)
    }.justifyContent(FlexAlign.Start).width('100%')
  }
}

标签:鸿蒙,url,100%,router,跳转,pushUrl,Router,路由,页面
From: https://blog.csdn.net/m0_68038853/article/details/140284548

相关文章

  • 【最新鸿蒙应用开发】——Navigation路由管理
    Navigation路由1.引言一多开发的项目适合使用Navigation进行统一的页面路由管理。Navigation还提供统一的标题栏、工具栏、菜单栏,并且自带导航返回功能。另外,Navigation还支持一些Router不支持的功能,比如:自带的路由拦截功能,自带的沉浸式功能等等。效果图预览代码链接:Navi......
  • 【最新鸿蒙应用开发】——实现鸿蒙的动画效果
    鸿蒙动画效果UI(用户界面)中包含开发者与设备进行交互时所看到的各种组件(如时间、壁纸等)。属性作为接口,用于控制组件的行为。例如,开发者可通过位置属性调整组件在屏幕上的位置。属性值的变化,通常会引起UI的变化。动画可在UI发生改变时,添加流畅的过渡效果。如果不加入动画,属性将......
  • 鸿蒙开发的语言应该怎么选?
    省流推荐ArkTS(支持HarmonyOSNext),放弃类JS开发方式,也不推荐仓颉鸿蒙开发的语言应该怎么选?在2024/06之前,官方文档【3.0/4.1】中尚有大篇幅的Web开发文档,并且在2019-2023年,每年的鸿蒙开发者大会上,多次提到过Web开发模式然而在2024年开发者大会上,官方不在提及这......
  • 前端学习-flutter学习-005-路由管理
    《Flutter实战·第二版》简单示例-跳转页面import'package:flutter/material.dart';import'dart:ui';//import'package:flutter/cupertino.dart';//voidmain(){//runApp(constMyApp());//}voidmain()=>runApp(constMyApp());//v......
  • 鸿蒙开发小案例(名片管理))
    鸿蒙开发小案例(名片管理)1、页面效果1.1初始页面1.2点击名片展开1.3点击收藏1.4点击编辑按钮2、实现代码2.1DataModel.ets2.2RandomUtil.ets2.3ContactList.ets1、页面效果1.1初始页面1.2点击名片展开1.3点击收藏1.4点击编辑按钮2、实现代码2......
  • 华为鸿蒙操作系统:创新与突破
    引言华为鸿蒙(HarmonyOS)作为华为自主研发的操作系统,自发布以来引起了广泛关注。它不仅是华为在美国制裁下的应对措施,更是科技企业在操作系统领域的一次重大突破。本文将探讨鸿蒙操作系统的背景、技术特点、应用场景以及其对未来的影响。背景市场需求随着物联网(IoT)时代的到来......
  • 硅纪元视角 | 国内首款鸿蒙人形机器人“夸父”开启应用新篇章
    在数字化浪潮的推动下,人工智能(AI)正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展,捕捉行业动态;提供深入的新闻解读,助您洞悉技术背后的逻辑;汇聚行业专家的见解,分享独到的视角和思考;精选对您有价值的信息,帮助您在AI时代中把握机遇。1分钟速览新闻  AI......
  • 前端react入门day06-ReactRouter
    (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)目录什么是前端路由创建路由开发环境快速开始抽象路由模块路由导航什么是路由导航声明式导航编程式导航导航传参嵌套路由配置什么是嵌套路由嵌套路由配置默认二级路由404路由配......
  • 将Linux做成路由器
    将Linux做成一个路由器主机名IPoe01192.168.200.170(外网)192.168.100.164(内网)oe02192.168.100.162(内网)通过这个规划表,oe02这个主机是只有一个内网网卡的,无法上网,我们需要将oe01这个Linux做成一个路由器,也就是从内网网卡收到的流量转发到外网网卡,然后出去路......
  • 5、flask-路由参数
     这里延续上一节的内容#路由+视图函数fromflaskimportBlueprint#frommodelsimport*#蓝图#创建蓝图对象#第一个参数:蓝图的名字#第二个参数:蓝图的包名blue=Blueprint('user',__name__,)@blue.route('/')#路由defindex():return'user......