ArkUI router.pushUrl:页面能跳只是第一步

举报
蓝瘦的蜕变 发表于 2026/09/14 22:37:24 2026/09/14
【摘要】 今天我们用 router.pushUrl 做一个最普通的页面跳转。 路由第一步很简单:点按钮,打开另一个页面。但真正容易出问题的地方不在按钮,而在 URL、页面栈和调用时机。我们先把最小闭环跑通,再把边界记住。 先准备一个承接页 Demo 里入口页只做一件事:跳到 ArkUIRouterTargetDemo。承接页也只

ArkUI router.pushUrl:页面能跳只是第一步

今天我们用 router.pushUrl 做一个最普通的页面跳转。

路由第一步很简单:点按钮,打开另一个页面。但真正容易出问题的地方不在按钮,而在 URL、页面栈和调用时机。我们先把最小闭环跑通,再把边界记住。

先准备一个承接页

Demo 里入口页只做一件事:跳到 ArkUIRouterTargetDemo。承接页也只做一件事:告诉你已经跳过来了,并提供一个回到上一页的按钮。

这比一上来写业务详情页更清楚。路由没跑通之前,不要急着塞数据请求、表单提交、弹窗确认这些内容。

用当前 UI 上下文里的 Router

按钮点击时页面已经渲染完成,这时调用:

this.getUIContext().getRouter().pushUrl({ url: this.targetUrl })

这样 Router 和当前 UI 上下文是绑定的。一般来说,比在不明确的地方直接调全局对象更稳。

先记住几个约束

Router 模式下,页面栈最多支持 32 个页面。你不能把每次点击都当成无限压栈。

另外,URL 必须指向已经声明过的页面。URL 写错、页面不存在,都会跳转失败。params 也只适合放可序列化数据,不要往里面塞函数、系统对象或者临时上下文。

你可以先把这个 Demo 跑起来,再故意改错 URL 看看失败表现。你平时写跳转时,是先确认 URL,还是等页面打不开了再回头查?

入口页完整代码

@Entry
@Component
struct ArkUIRouterPushDemo {
  private targetUrl: string = 'pages/arkUI/route/ArkUIRouterTargetDemo'

  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 6 }) {
      Text(title)
        .fontSize(19)
        .fontWeight(FontWeight.Bold)
        .fontColor('#111827')
      Text(desc)
        .fontSize(13)
        .fontColor('#6B7280')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  build() {
    Scroll() {
      Column({ space: 22 }) {
        Column({ space: 8 }) {
          Text('ArkUI router.pushUrl')
            .fontSize(28)
            .fontWeight(FontWeight.Bold)
            .fontColor('#111827')
          Text('页面能跳只是第一步')
            .fontSize(16)
            .fontColor('#4B5563')
          Text('pushUrl 会把新页面压到页面栈顶。它适合简单页面跳转,但 URL 必须指向已经声明过的页面。')
            .fontSize(14)
            .fontColor('#6B7280')
            .lineHeight(22)
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)

        this.sectionTitle('先把目标 URL 写清楚', 'URL 写错或目标页不存在时,跳转会失败。Demo 里只跳到一个简单承接页。')
        Column({ space: 10 }) {
          Text('目标页')
            .fontSize(14)
            .fontColor('#6B7280')
            .width('100%')
          Text(this.targetUrl)
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
            .fontColor('#2563EB')
            .width('100%')
        }
        .width('100%')
        .padding(16)
        .borderRadius(14)
        .backgroundColor('#FFFFFF')
        .border({ width: 1, color: '#E5E7EB' })
        .alignItems(HorizontalAlign.Start)

        this.sectionTitle('用当前 UI 上下文里的 Router', '按钮点击时页面已经渲染完成,这时再调用 pushUrl,UI 上下文也更明确。')
        Button('跳到承接页')
          .fontSize(15)
          .fontColor('#FFFFFF')
          .height(44)
          .borderRadius(22)
          .backgroundColor('#2563EB')
          .padding({ left: 22, right: 22 })
          .onClick(() => {
            this.getUIContext().getRouter().pushUrl({ url: this.targetUrl })
          })

        this.sectionTitle('先记住几个边界', 'Router 页面栈最多支持 32 个页面;params 只放可序列化数据;不要在页面还没渲染完时急着跳。')
        Text('这篇只讲最普通的页面压栈。替换页面、单实例、清栈这些能力后面再单独拆,不在第一篇里塞满。')
          .fontSize(14)
          .fontColor('#374151')
          .lineHeight(22)
          .width('100%')
          .padding(16)
          .borderRadius(14)
          .backgroundColor('#F9FAFB')
          .border({ width: 1, color: '#E5E7EB' })
      }
      .width('100%')
      .padding(24)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F3F4F6')
  }
}

承接页完整代码

@Entry
@Component
struct ArkUIRouterTargetDemo {
  @Builder
  infoRow(label: string, value: string) {
    Row({ space: 10 }) {
      Text(label)
        .fontSize(14)
        .fontColor('#6B7280')
        .width(86)
      Text(value)
        .fontSize(14)
        .fontColor('#111827')
        .layoutWeight(1)
    }
    .width('100%')
  }

  build() {
    Column({ space: 22 }) {
      Column({ space: 8 }) {
        Text('承接页')
          .fontSize(28)
          .fontWeight(FontWeight.Bold)
          .fontColor('#111827')
        Text('我们已经通过 pushUrl 来到这里')
          .fontSize(16)
          .fontColor('#4B5563')
        Text('这个页面只负责证明跳转成功。需要离开时,点下面的按钮回到上一页。')
          .fontSize(14)
          .fontColor('#6B7280')
          .lineHeight(22)
      }
      .width('100%')
      .alignItems(HorizontalAlign.Start)

      Column({ space: 12 }) {
        this.infoRow('页面作用', '承接 pushUrl 跳转')
        this.infoRow('返回方式', '调用 back() 回到上一页')
        this.infoRow('本页参数', '不接收参数')
      }
      .width('100%')
      .padding(16)
      .borderRadius(14)
      .backgroundColor('#FFFFFF')
      .border({ width: 1, color: '#E5E7EB' })

      Button('回到上一页')
        .fontSize(15)
        .fontColor('#FFFFFF')
        .height(44)
        .borderRadius(22)
        .backgroundColor('#2563EB')
        .padding({ left: 22, right: 22 })
        .onClick(() => {
          this.getUIContext().getRouter().back()
        })
    }
    .width('100%')
    .height('100%')
    .padding(24)
    .backgroundColor('#F3F4F6')
    .alignItems(HorizontalAlign.Start)
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。