文章目录
一、路由
- 路由配置
uni-app页面路由为框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同。 - 路由跳转
uni-app 有两种页面路由跳转方式:
- 使用 navigator组件跳转(标签式导航)
- 调用 API跳转(编程式导航)
注
- 页面返回时会自动关闭 loading 及 toast, modal 及 actionSheet 不会自动关闭。
- 页面关闭时,只是销毁了页面实例,未完成的网络请求、计时器等副作用需开发者自行处理。
- 页面栈
框架以栈的形式管理当前所有页面,当发生路由切换的时候,页面栈的表现如下:
路由方式 | 页面栈表现 | 触发时机 |
---|---|---|
初始化 | 新页面入栈 | uni-app 打开的第一个页面 |
打开新页面 | 新页面入栈 | 调用 API uni.navigateTo 、使用组件 <navigator open-type="navigate"/> |
页面重定向 | 当前页面出栈,新页面入栈 | 调用 API uni.redirectTo 、使用组件 <navigator open-type="redirectTo"/> |
页面返回 | 页面不断出栈,直到目标返回页 | 调用 API uni.navigateBack 、使用组件 <navigator open-type="navigateBack"/> 、用户按左上角返回按钮、安卓用户点击物理back按键 |
Tab 切换 | 页面全部出栈,只留下新的 Tab 页面 | 调用 API uni.switchTab 、使用组件 <navigator open-type="switchTab"/> 、用户切换 Tab |
重加载 | 页面全部出栈,只留下新的页面 | 调用 API uni.reLaunch 、使用组件 <navigator open-type="reLaunch"/> |
二、页面调用接口
- getApp()
getApp() 函数用于获取当前应用实例,一般用于获取globalData。也可通过应用实例调用 App.vue methods 中定义的方法。
cpp
// app.vue页面
methods: {
doSomething() {
console.log('doSomething')
}
}
// 组价页面
mounted() {
const app = getApp()
console.log(app.globalData)
app.doSomething() // 调用
}
注
- 不要在定义于 App() 内的函数中,或调用 App 前调用 getApp() ,可以通过 this.$scope 获取对应的app实例
- 通过 getApp() 获取实例之后,不要私自调用生命周期函数。
- 当在首页nvue中使用getApp()不一定可以获取真正的App对象。对此提供了const app = getApp({allowDefault: true})用来获取原始的App对象,可以用来在首页对globalData等初始化
- getCurrentPages()
getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,数组中的元素为页面实例,第一个元素为首页,最后一个元素为当前页面。
方法 | 描述 | 平台说明 |
---|---|---|
page.$getAppWebview() | 获取当前页面的webview对象实例 | App |
page.$vm | 当前页面的 Vue 实例 | |
page.route | 获取当前页面的路由 |
注意:
- getCurrentPages() 仅用于展示页面栈的情况,请勿修改页面栈,以免造成页面状态错误。
页面关闭时,对应页面实例会在页面栈中删除。- navigateTo, redirectTo 只能打开非 tabBar 页面。
- switchTab 只能打开 tabBar 页面。
- `reLaunch`` 可以打开任意页面。
- 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
- 不能在首页 onReady 之前进行页面跳转。
- $getAppWebview()
-
uni-app 在 getCurrentPages()获得的页面里内置了一个方法 $getAppWebview() 可以得到当前webview的对象实例,从而实现对 webview 更强大的控制。在 html5Plus 中,plus.webview具有强大的控制能力,
-
但uni-app框架有自己的窗口管理机制,请不要自己创建和销毁webview,如有需求覆盖子窗体上去,请使用原生子窗体subNvue。
注意:此方法仅 App 支持
cppexport default { data() { return { title: 'Hello' } }, onLoad() { // #ifdef APP-PLUS const currentWebview = this.$scope.$getAppWebview(); //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效 currentWebview.setBounce({position:{top:'100px'},changeoffset:{top:'0px'}}); //动态重设bounce效果 // #endif } }
获取指定页面 webview 的对象实例
getCurrentPages()可以得到所有页面对象,然后根据数组,可以取指定的页面webview对象
cppvar pages = getCurrentPages(); var page = pages[pages.length - 1]; // #ifdef APP-PLUS var currentWebview = page.$getAppWebview(); console.log(currentWebview.id);//获得当前webview的id console.log(currentWebview.isVisible());//查询当前webview是否可见 ); // #endif
uni-app自带的web-view组件,是页面中新插入的一个子webview。获取该对象的方法见:https://ask.dcloud.net.cn/article/35036
二、路由跳转
1.uni.navigateTo(OBJECT)
保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。
参数 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
url | String | 是 | 需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 'path?key=value&key2=value2',path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数 | ||
animationType | String | 否 | pop-in | 窗口显示的动画效果 | App |
animationDuration | Number | 否 | 300 | 窗口动画持续时间,单位为 ms | App |
events | Object | 否 | 页面间通信接口,用于监听被打开页面发送到当前页面的数据。2.8.9+ 开始支持。 | ||
success | Function | 否 | 接口调用成功的回调函数 | ||
fail | Function | 否 | 接口调用失败的回调函数 | ||
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
cpp
//在起始页面跳转到test.vue页面并传递参数
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});
cpp
// 在test.vue页面接受参数
export default {
onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
console.log(option.id); //打印出上个页面传递的参数。
console.log(option.name); //打印出上个页面传递的参数。
}
}
cpp
// 在起始页面跳转到test.vue页面,并监听test.vue发送过来的事件数据
uni.navigateTo({
url: '/pages/test?id=1',
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log(data)
},
someEvent: function(data) {
console.log(data)
}
...
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'data from starter page' })
}
})
// 在test.vue页面,向起始页通过事件传递数据
onLoad: function(option) {
const eventChannel = this.getOpenerEventChannel();
eventChannel.emit('acceptDataFromOpenedPage', {data: 'data from test page'});
eventChannel.emit('someEvent', {data: 'data from test page for someEvent'});
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
eventChannel.on('acceptDataFromOpenerPage', function(data) {
console.log(data)
})
}
vue3.0 script setup 语法糖中调用 getOpenerEventChannel 示例:
cpp
<script setup>
import {
onMounted,
getCurrentInstance
} from 'vue';
onMounted(() => {
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel();
eventChannel.emit('acceptDataFromOpenedPage', {
data: 'data from test page'
});
eventChannel.emit('someEvent', {
data: 'data from test page for someEvent'
});
eventChannel.on('acceptDataFromOpenerPage', function(data) {
console.log('acceptDataFromOpenerPage', data)
})
})
</script>
url有长度限制,太长的字符串会传递失败,可改用页面通信、全局变量,另外参数中出现空格等特殊字符时需要对参数进行编码,如下为使用encodeURIComponent对参数进行编码的示例。
cpp
<navigator :url="'/pages/test/test?item='+ encodeURIComponent(JSON.stringify(item))"></navigator>
cpp
// 在test.vue页面接受参数
onLoad: function (option) {
const item = JSON.parse(decodeURIComponent(option.item));
}
注意:
- 页面跳转路径有层级限制,不能无限制跳转新页面
- 跳转到 tabBar 页面只能使用 switchTab 跳转
- 路由API的目标页面必须是在pages.json里注册的vue页面。
- 如果想打开web url,
在App平台可以使用 plus.runtime.openURL 或web-view组件
H5平台使用 window.open;
小程序平台使用web-view组件(url需在小程序的联网白名单中)。
在hello uni-app中有个组件ulink.vue已对多端进行封装,可参考。
2.uni.redirectTo(OBJECT)
关闭当前页面,跳转到应用内的某个页面。
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
url | String | 是 | 需要跳转的应用内非 tabBar 的页面的路径,路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 'path?key=value&key2=value2' |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
c
uni.redirectTo({
url: '/pages/test?id=1'
});
注意:
跳转到 tabBar 页面只能使用 switchTab 跳转
3.uni.reLaunch(OBJECT)
关闭所有页面,打开到应用内的某个页面。
注意:
- 如果调用了 uni.preloadPage(OBJECT) 不会关闭,仅触发生命周期 onHide
- H5端调用uni.reLaunch之后之前页面栈会销毁,但是无法清空浏览器之前的历史记录, 此时navigateBack不能返回,
如果存在历史记录的话点击浏览器的返回按钮或者调用history.back()仍然可以导航到浏览器的其他历史记录。
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
url | String | 是 | 需要跳转的应用内页面路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 'path?key=value&key2=value2',如果跳转的页面路径是 tabBar 页面则不能带参数 |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
cpp
uni.reLaunch({
url: '/pages/test?id=1'
})
cpp
export default {
onLoad: function (option) {
console.log(option.id);
}
}
4.uni.switchTab(OBJECT)
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
注意:
如果调用了 uni.preloadPage(OBJECT) 不会关闭,仅触发生命周期 onHide
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
url | String | 是 | 需要跳转的 tabBar 页面的路径(需在 pages.json 的 tabBar 字段定义的页面),路径后不能带参数 |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
cpp
// page.json
{
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首页"
},{
"pagePath": "pages/other/other",
"text": "其他"
}]
}
}
cpp
// other.vue
uni.switchTab({
url: '/pages/index/index'
});
5.uni.navigateBack(OBJECT)
关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。
参数 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
delta | Number | 否 | 1 | 返回的页面数,如果 delta 大于现有页面数,则返回到首页。 | |
animationType | String | 否 | pop-out | 窗口关闭的动画效果 | App |
animationDuration | Number | 否 | 300 | 窗口关闭动画的持续时间,单位为 ms果 | App |
success | Function | 否 | 接口调用成功的回调函数 | ||
fail | Function | 否 | 接口调用失败的回调函数 | ||
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
cpp
// 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码
// 此处是A页面
uni.navigateTo({
url: 'B?id=1'
});
// 此处是B页面
uni.navigateTo({
url: 'C?id=1'
});
// 在C页面内 navigateBack,将返回A页面
uni.navigateBack({
delta: 2
});
总结
页面跳转方式,总结
- navigateTo 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack 可以返回到原页面
- redirectTo 关闭当前页面,跳转到应用内的某个页面
- switchTab 跳转到tabBar页面,同时关闭其他非tabBar页面
- navigateBack 返回上一页面
- reLanch 关闭所有页面,打开到应用内的某个页面
页面栈的关系 - navigateTo 新页面入栈
- redirectTo 当前页面出栈,新页面出栈
- switchTab 页面全部出栈,只留下新的Tab页面
- navigateBack 页面不断出栈,知道目标返回页,新页面入栈
- reLanch 页面全部出栈,只留下新的页面