We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
页面路由是指在应用程序中实现不同页面之间的跳转和数据传递。
案例:第一次使用某个购物应用,打开时肯定会是一个登录页,在登录成功以后,会跳转到首页,然后可能会去搜索,就会进入到搜索列表页,接着呢如果搜索到某一个感兴趣的商品A,点击,就会进入到商品A的详情页,到现在为止已经访问了好多不同的页面,并且在它们之间完成了跳转,那我之前访问过的页面都去哪里了?是不是全部被销毁了?其实并没有,我们在页面跳转之间访问过的所有页面,都会被 HarmonyOS 保存到页面栈的空间当中。页面栈顾名思义就是保存页面的栈结构空间,栈结构是先进后出,所以呢,我们最早访问的登录页就被压到了栈的最底层,而当前正在访问的商品A的详情页就在栈顶。也就是说,谁在栈顶,当前显示的就是谁的页面。那么 HarmonyOS 为啥要把这些访问过的页面保存起来,而不是直接销毁掉呢?放在这里不占用内存吗?这其实是我们的页面功能需要去用到这些历史页面。一般商品详情页都会有返回按钮,当点击返回按钮,应该返回到之前访问过的搜索列表页,有了页面栈,想要实现这个功能就非常简单了。只需要在点击返回时,把栈顶的这个页面移除,这样一来,紧挨着栈顶的搜索列表页就成为了新的栈顶页面,现在显示的就是搜索列表页,从而也就实现了返回的效果。如果现在想做页面跳转,过程就相反,比如在搜索列表页点击商品B,只需要把商品B的详情页创建出来,然后压入栈里,现在栈顶就是商品B的详情页,从而实现了跳转效果。简单来讲,如果想实现创建页面,就压入栈;如果想实现返回,就把栈顶页面弹出栈,即可。
页面栈
页面栈的最大容量:
页面栈的最大容量上限为 32 个页面。就是说如果我们不断的去访问新的页面,往栈里压入页面,可能就会达到上限,这时候再想访问这个页面,再想往里面去压栈,就会报错,这时候就不得不去调用 router.clear() 方法去清空页面栈,就会把历史页面干掉,释放内存。但是,一旦把历史页面干掉,再想返回前一个页面就访问不了了。所以 router.clear() 要慎重使用。我们在开发的过程中一定要想办法控制页面栈里的页面数量,不要让它达到上限,而不是说等达到上限去清空。
32
router.clear()
怎么去控制页面栈里的页面数量呢?就要使用页面栈不同的跳转行为模式。Router 有两种页面跳转模式:
router.pushUrl():目标页不会替换当前页,而是压入页面栈。比如当前在商品A的详情页,如果点击商品B的图片,就需要压入栈,就需要创建一个商品B的页面,把商品B的详情页压入栈顶,这时候,原有的商品A的详情页不会被移除,而是压到栈的内部,成为一个历史页面,因此点返回按钮,用 router.back() 就会返回到历史页面商品A的详情页。但是,这种实现方式会导致栈里的页面会越来越多。
router.pushUrl()
router.back()
router.replaceUrl():目标页替换当前页,当前页会被销毁并释放资源。也就是说从商品A的详情页跳转到商品B的详情页,这时候商品A的详情页就变成了历史页,会直接被销毁,而不是在栈内保存。这样一来,内存就节省出来,但是如果想从商品B的详情页返回到商品A的详情页,就返回不了了。
router.replaceUrl()
何时使用 router.pushUrl(),何时又使用 router.replaceUrl() 呢?
举个例子,比如说,我们的登录页,只有在第一次打开的时候才需要,只要不退出,就不用再登录。所以登录页基本上就访问一次,而且也不需要返回,登录页保存在历史页面栈里没有任何意义,所以在登录成功以后,跳转到首页时,就可以使用 router.replaceUrl() 把登录页销毁;如果我们从首页跳转到搜索列表页,如果这时候点返回,返回到首页,所以我们的首页应该在页面栈里保存,作为一个历史页面,就要用 router.pushUrl()。
如果商品A的详情页和商品B的详情页来回切换,如果用到 router.pushUrl(),会导致页面栈的容量一会儿就满了,就要用到页面实例模式,Router 有两种页面实例模式:
Standard:标准实例模式,每次跳转都会新建一个目标页并压入栈顶。默认就是这种模式。
Standard
Single:单实例模式,顾名思义,每一个页面只会存在一份,如果目标页已经在栈中,则离栈顶最近的同Url页面会被移动到栈顶并重新加载。
Single
结合合适的跳转模式(router.pushUrl()、router.replaceUrl())和实例模式(Standard、Single),就能够控制页面栈里的页面数量,避免达到上限。
首先要导入 HarmonyOS 提供的 Router 模块:
import router from '@ohos.router';
然后利用 router 实现跳转、返回等操作:
router.pushUrl( { url: 'pages/PageA', params: { id: 1 } }, router.RouterMode.Single, err => { if (err) { console.log('路由失败。') } } )
RouterOptions
RouterMode
异常响应回调函数
目标页获取传递过来的参数
params: any = router.getParams()
目标页返回上一页
目标页返回指定页,并携带参数
router.back({ url: 'pages/Index', params: { id: 10 } })
代码目录结构
|____src | |____main | | |____resources | | | | |____profile | | | | | |____main_pages.json | | | | |____media | | | | | |____back.png | | |____ets | | | |____components | | | | |____CommonComponents.ets | | | |____pages | | | | |____PageD.ets | | | | |____PageC.ets | | | | |____PageB.ets | | | | |____PageA.ets | | | | |____Index.ets
main_pages.json
{ "src": [ "pages/Index", "pages/PageA", "pages/PageB", "pages/PageC", "pages/PageD" ] }
CommonComponents.ets
import router from '@ohos.router' @Component export struct Header { @State params: any = router.getParams() build() { Row({ space: 5 }) { Image($r('app.media.back')) .width(30) .onClick(() => { // 返回前的警告 router.showAlertBeforeBackPage({ message: 'Show Alert Before Back Page' }) // 返回上一页 router.back() }) if (this.params) { Text(`Params id: ${this.params.id}`) .fontSize(28) .fontWeight(FontWeight.Bold) } } .width('98%') .height(30) } }
Index.ets
import router from '@ohos.router' class RouterInfo { // 页面路径 url: string // 页面标题 title: string constructor(url: string, title: string) { this.url = url this.title = title } } @Entry @Component struct Index { @State message: string = '页面列表' private routers: RouterInfo[] = [ new RouterInfo('pages/PageA', 'A页面'), new RouterInfo('pages/PageB', 'B页面'), new RouterInfo('pages/PageC', 'C页面'), new RouterInfo('pages/PageD', 'D页面') ] build() { Column() { Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) .height(80) List({ space: 15 }) { ForEach( this.routers, (router, index) => { ListItem() { this.RouterItem(router, index + 1) } } ) } .layoutWeight(1) .alignListItem(ListItemAlign.Center) .width('100%') } .width('100%') .height('100%') } @Builder RouterItem(r: RouterInfo, i: number) { Row() { Text(i + '. ') .fontSize(20) .fontColor(Color.White) Text(r.title) .fontSize(20) .fontColor(Color.White) } .width('90%') .padding(12) .backgroundColor('#38F') .borderRadius(20) .shadow({ radius: 6, color: '#4F000000', offsetX: 2, offsetY: 2 }) .onClick(() => { // router 跳转 router.pushUrl( { url: r.url, params: { id: i } }, router.RouterMode.Single, err => { if (err) { console.log(`路由失败,errCode: ${err.code} errMsg: ${err.message}`) } } ) }) } }
PageA.ets
import { Header } from '../components/CommonComponents' @Entry @Component struct PageA { @State message: string = 'Page A' build() { Column() { Header() Row() { Column() { Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) } .width('100%') } .height('100%') }.width('100%') } }
运行效果
页面栈的最大容量上限为 32 个页面,使用 router.clear() 方法可以清空页面栈,释放内存。
Router 有两种页面跳转模式,分别是:
Router 有两种页面实例模式,分别是:
router 的使用步骤:
The text was updated successfully, but these errors were encountered:
No branches or pull requests
一、概念
页面路由是指在应用程序中实现不同页面之间的跳转和数据传递。
页面栈的最大容量:
页面栈的最大容量上限为
32
个页面。就是说如果我们不断的去访问新的页面,往栈里压入页面,可能就会达到上限,这时候再想访问这个页面,再想往里面去压栈,就会报错,这时候就不得不去调用router.clear()
方法去清空页面栈,就会把历史页面干掉,释放内存。但是,一旦把历史页面干掉,再想返回前一个页面就访问不了了。所以router.clear()
要慎重使用。我们在开发的过程中一定要想办法控制页面栈里的页面数量,不要让它达到上限,而不是说等达到上限去清空。怎么去控制页面栈里的页面数量呢?就要使用页面栈不同的跳转行为模式。Router 有两种页面跳转模式:
router.pushUrl()
:目标页不会替换当前页,而是压入页面栈。比如当前在商品A的详情页,如果点击商品B的图片,就需要压入栈,就需要创建一个商品B的页面,把商品B的详情页压入栈顶,这时候,原有的商品A的详情页不会被移除,而是压到栈的内部,成为一个历史页面,因此点返回按钮,用router.back()
就会返回到历史页面商品A的详情页。但是,这种实现方式会导致栈里的页面会越来越多。router.replaceUrl()
:目标页替换当前页,当前页会被销毁并释放资源。也就是说从商品A的详情页跳转到商品B的详情页,这时候商品A的详情页就变成了历史页,会直接被销毁,而不是在栈内保存。这样一来,内存就节省出来,但是如果想从商品B的详情页返回到商品A的详情页,就返回不了了。何时使用
router.pushUrl()
,何时又使用router.replaceUrl()
呢?举个例子,比如说,我们的登录页,只有在第一次打开的时候才需要,只要不退出,就不用再登录。所以登录页基本上就访问一次,而且也不需要返回,登录页保存在历史页面栈里没有任何意义,所以在登录成功以后,跳转到首页时,就可以使用
router.replaceUrl()
把登录页销毁;如果我们从首页跳转到搜索列表页,如果这时候点返回,返回到首页,所以我们的首页应该在页面栈里保存,作为一个历史页面,就要用router.pushUrl()
。如果商品A的详情页和商品B的详情页来回切换,如果用到
router.pushUrl()
,会导致页面栈的容量一会儿就满了,就要用到页面实例模式,Router 有两种页面实例模式:Standard
:标准实例模式,每次跳转都会新建一个目标页并压入栈顶。默认就是这种模式。Single
:单实例模式,顾名思义,每一个页面只会存在一份,如果目标页已经在栈中,则离栈顶最近的同Url页面会被移动到栈顶并重新加载。二、Router API 用法
首先要导入 HarmonyOS 提供的 Router 模块:
然后利用 router 实现跳转、返回等操作:
RouterOptions
RouterMode
异常响应回调函数
目标页获取传递过来的参数
目标页返回上一页
目标页返回指定页,并携带参数
三、示例
代码目录结构
main_pages.json
CommonComponents.ets
Index.ets
PageA.ets
运行效果
四、总结
页面栈的最大容量上限为
32
个页面,使用router.clear()
方法可以清空页面栈,释放内存。Router 有两种页面跳转模式,分别是:
router.pushUrl()
:目标页不会替换当前页,而是压入页面栈,因此可以用router.back()
返回当前页。router.replaceUrl()
:目标页会替换当前页,当前页会被销毁并释放资源,无法返回当前页。Router 有两种页面实例模式,分别是:
Standard
:标准实例模式,每次调整都会新建一个目标并压入栈顶。默认就是这种模式。Single
:单实例模式,如果目标页已经在栈中,则离栈顶最近的同 url 页面会被移动到栈顶并重新加载。router 的使用步骤:
The text was updated successfully, but these errors were encountered: