页面路由(router)是指在应用程序中实现不同页面之间的跳转和数据传递。
HarmonyOS 提供了 Router 模块,通过不同的 url 地址,可以方便地进行页面路由,轻松地访问不同的页面。
类似这样的效果:
页面跳转是开发过程中的一个重要组成部分。在使用应用程序时,通常需要在不同的页面之间跳转,有时还需要将数据从一个页面传递到另一个页面(类似 Activity 跳转)。
Router 模块:提供了两种 跳转模式,分别是 router.pushUrl() 和 router.replaceUrl()。
这两种模式决定了目标页是否会替换当前页。
跳转模式 | 说明 |
---|---|
router.pushUrl() | 目标页不会替换当前页,而是压入页面栈。这样可以保留当前页的状态,并且可以通过返回键或者调用 router.back() 方法返回到当前页。 |
router.replaceUrl() | 目标页会替换当前页,并销毁当前页。这样可以释放当前页的资源,并且无法返回到当前页。 |
Router 模块:提供了两种 实例模式,分别是 Standard 和 Single。
这两种模式决定了目标 url 是否会对应多个实例。
实例模式 | 说明 |
---|---|
Standard | 标准实例模式,也是默认情况下的实例模式。 每次调用该方法都会新建一个目标页,并压入栈顶。 |
Single | 单实例模式。如果目标页的 url 在页面栈中已经存在同 url 页面, 则离栈顶最近的同 url 页面会被移动到栈顶,并重新加载; 如果目标页的 url 在页面栈中不存在同 url 页面,则按照标准模式跳转。 |
构建第一个界面
接下来我们实操一下,首先创建一个功能,默认的界面代码如下:
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
运行效果:
在默认页面基础上,我们添加一个 Button 组件,作为按钮响应用户点击,从而实现跳转到另一个页面。
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 添加按钮,以响应用户点击
Button() {
Text('Next').fontSize(30).fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({ top: 20 })
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
}
.width('100%')
}
.height('100%')
}
}
运行效果:
构建第二个界面
接下来创建第二个我们需要跳转的界面。
新建第二个页面文件。在“Project”窗口,打开“entry > src > main > ets ”,右键点击“pages”文件夹,选择“New > ArkTS File”,命名为“Second”,点击“Finish”。
创建好 Second.ets 后,需要 手动配置 好第二个界面的路由信息。
在“Project”窗口,打开“entry > src > main > resources > base > profile”,在 main_pages.json 文件中的“src”下配置第二个页面的路由“pages/Second”。示例如下:
如果你仔细的话,会发现上面我对手动配置加粗了,其实创建新的界面还有更简洁的方法。
我们可以在右键点击“pages”文件夹时,选择“New > Page”,这样的话就无需手动配置相关页面路由了,比如我们再创建一个新的界面:Third.ets。
你会发现 main_pages.json 会默认添加 Third 界面的路由:
{
"src": [
"pages/Index",
"pages/Second",
"pages/Third"
]
}
刚刚创建的 Second 页面没有任何代码,我们添加相关文本,并且我们也给它搞一个 Button。
预览效果:
实现界面跳转
在使用页面路由 Router 相关功能之前,我们需要在代码中先导入 Router 模块:
import router from '@ohos.router';
router.pushUrl()
import router from '@ohos.router' // 导入页面路由模块
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 添加按钮,以响应用户点击
Button() {
Text('Next').fontSize(30).fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({ top: 20 })
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
// 跳转按钮绑定 onClick 事件,点击时跳转到第二页
.onClick(() => {
// 跳转到第二页
router.pushUrl({ url: 'pages/Second' })
})
}
.width('100%')
}
.height('100%')
}
}
这样就可以实现页面的跳转了,看下效果:
router.back()
在第二个页面中,我们可以给返回按钮绑定 onClick 事件,点击按钮时返回到第一页。
import router from '@ohos.router'
@Entry
@Component
struct Second {
@State message: string = 'Hi there'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button() {
Text('Back')
.fontSize(25)
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({
top: 20
})
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
.onClick(() => {
router.back() // 返回到第一页
})
}
.width('100%')
}
.height('100%')
}
}
运行效果:
router.replaceUrl
router.replaceUrl 主要用于目标页替换当前页,并销毁当前页。比如有一个常用场景:一个登录页(Login)和一个个人中心页,希望从登录页成功登录后,跳转到个人中心页。同时销毁登录页,再返回时直接退出应用。
import router from '@ohos.router'
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 添加按钮,以响应用户点击
Button() {
Text('Next').fontSize(30).fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({ top: 20 })
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
.onClick(() => {
// router.replaceUrl({ url: 'pages/Second' })
// replaceUrl 实现跳转后会销毁前一个页面
router.replaceUrl({ url: 'pages/Second' })
})
}
.width('100%')
}
.height('100%')
}
}
运行效果:
传递数据
如果需要在跳转时传递一些数据给目标页,则可以在调用 Router 模块的方法时,添加一个 params 属性,并指定一个对象作为参数。例如:
第一个页面
import router from '@ohos.router'
class DataModel {
info: String;
}
let paramsInfo: DataModel = {
info: '第一页传过来的数据'
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 添加按钮,以响应用户点击
Button() {
Text('Next').fontSize(30).fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({ top: 20 })
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
.onClick(() => {
router.pushUrl({
url: 'pages/Second',
params: paramsInfo
})
})
}
.width('100%')
}
.height('100%')
}
}
第二个页面
import router from '@ohos.router'
const params = router.getParams(); // 获取传递过来的参数对象
@Entry
@Component
struct Second {
@State message: string = 'Hi there'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Text(params['info'])
Button() {
Text('Back')
.fontSize(25)
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({
top: 20
})
.backgroundColor('#0D9FFB')
.width('40%')
.height('5%')
.onClick(() => {
router.back()
})
}
.width('100%')
}
.height('100%')
}
}
运行效果:
页面返回
返回上一个页面
上面我们其实已经看到了一个很简单的关于页面返回的例子,调用 router.back() 即可。
router.back();
返回到指定页面
另外,我们还可以添加 url 参数指定返回的界面。
router.back({
url: 'pages/Home'
});
比如现在工程里面还有一个 Third 的页面。
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
... ...
Button() {
Text('Next').fontSize(30).fontWeight(FontWeight.Bold)
}
... ...
.onClick(() => {
router.pushUrl({
url: 'pages/Second', // 跳转到第二个页面
params: paramsInfo
})
})
}
.width('100%')
}
.height('100%')
}
}
@Entry
@Component
struct Second {
@State message: string = 'Hi there'
build() {
Row() {
Column() {
... ...
Button() {
Text('Next')
.fontSize(25)
.fontWeight(FontWeight.Bold)
}
... ...
.onClick(() => {
router.pushUrl({
url: 'pages/Third' // 跳转到第三个页面
})
})
}
.width('100%')
}
.height('100%')
}
}
@Entry
@Component
struct Third {
@State message: string = 'Third Page'
build() {
Row() {
Column() {
... ...
Button() {
Text('Back')
.fontSize(25)
.fontWeight(FontWeight.Bold)
}
... ...
.onClick(() => {
router.pushUrl({
url: 'pages/Index'. // 指定 Third 返回到首页 Index
})
})
}
.width('100%')
}
.height('100%')
}
}
带参数信息返回
同样的,返回到指定页面也可以传递自定义参数信息。
router.back({
url: 'pages/Home',
params: {
info: '来自Home页'
}
});
在目标页中,在需要获取参数的位置调用 router.getParams() 方法即可。