路由与页面跳转
在uni-app中,路由功能是由框架统一管理的,开发者只需要配置页面路径,并调用相应的API进行页面跳转即可。本文将详细介绍uni-app的路由系统和页面跳转方法。
页面路由配置
uni-app的页面路由全部在pages.json
文件中进行配置,包括路径、窗口样式等。
基本配置
json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
}
},
{
"path": "pages/detail/detail",
"style": {
"navigationBarTitleText": "详情页"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}
配置说明
pages
:用于配置页面路径及窗口表现path
:页面路径,相对于项目根目录style
:页面窗口表现,如导航栏标题、背景色等
globalStyle
:全局默认的窗口表现
分包配置
对于较大型的应用,可以使用分包加载优化体验:
json
{
"pages": [
// 主包页面
],
"subPackages": [
{
"root": "pagesA",
"pages": [
{
"path": "list/list",
"style": { ... }
}
]
},
{
"root": "pagesB",
"pages": [
{
"path": "detail/detail",
"style": { ... }
}
]
}
]
}
路由跳转方式
uni-app提供了多种页面跳转API,适用于不同的场景。
1. uni.navigateTo(OBJECT)
保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack
可以返回到原页面。
javascript
uni.navigateTo({
url: '/pages/detail/detail?id=1&name=uniapp',
success: function(res) {
console.log('跳转成功');
},
fail: function(err) {
console.error('跳转失败', err);
},
complete: function() {
console.log('跳转完成');
}
});
注意事项:
- 页面栈最多十层,超出会无法跳转
url
参数中可以携带参数,如?key=value
形式
2. uni.redirectTo(OBJECT)
关闭当前页面,跳转到应用内的某个页面。
javascript
uni.redirectTo({
url: '/pages/detail/detail'
});
使用场景:
- 不希望用户返回上一页时(如登录成功后)
- 页面栈已经达到最大层级时
3. uni.reLaunch(OBJECT)
关闭所有页面,打开到应用内的某个页面。
javascript
uni.reLaunch({
url: '/pages/index/index'
});
使用场景:
- 需要重置应用状态时
- 切换到完全不同的功能模块时
4. uni.switchTab(OBJECT)
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
javascript
uni.switchTab({
url: '/pages/home/home'
});
注意事项:
- 只能跳转到在
pages.json
中定义的tabBar
页面 - 不能在
url
中传递参数
5. uni.navigateBack(OBJECT)
关闭当前页面,返回上一页面或多级页面。
javascript
uni.navigateBack({
delta: 1
});
参数说明:
delta
:返回的页面数,如果 delta 大于现有页面数,则返回到首页
页面传参
传递参数
在跳转页面时,可以通过url
参数传递数据:
javascript
uni.navigateTo({
url: '/pages/detail/detail?id=1&name=uniapp'
});
接收参数
在目标页面的onLoad
生命周期函数中接收参数:
javascript
export default {
onLoad(options) {
console.log(options.id); // 1
console.log(options.name); // uniapp
}
}
路由拦截与导航守卫
uni-app没有提供类似Vue Router的全局导航守卫,但可以通过以下方式实现类似功能:
1. 封装路由方法
javascript
// router.js
export default {
navigateTo(options) {
// 在这里添加前置检查逻辑
if (!getApp().globalData.isLogin && options.url.indexOf('/pages/user/') !== -1) {
// 未登录且访问需要登录的页面,跳转到登录页
uni.navigateTo({
url: '/pages/login/login'
});
return;
}
// 正常跳转
uni.navigateTo(options);
}
}
2. 使用混入(mixin)
javascript
// routerMixin.js
export default {
onShow() {
// 页面显示时的检查逻辑
this.checkRoutePermission();
},
methods: {
checkRoutePermission() {
// 权限检查逻辑
}
}
}
然后在页面中使用:
javascript
import routerMixin from '@/mixins/routerMixin';
export default {
mixins: [routerMixin],
// 页面其他配置
}
页面栈管理
获取当前页面栈
javascript
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
const prevPage = pages[pages.length - 2];
页面栈操作示例
- 返回上一页并传值:
javascript
// 在当前页面
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];
// 直接修改上一页的数据
prevPage.$vm.dataList = newDataList;
// 返回上一页
uni.navigateBack();
- 返回指定页面:
javascript
const pages = getCurrentPages();
let pageIndex = -1;
// 查找目标页面在页面栈中的位置
for (let i = 0; i < pages.length; i++) {
if (pages[i].route === 'pages/target/target') {
pageIndex = i;
break;
}
}
if (pageIndex !== -1) {
// 计算需要返回的层级
const delta = pages.length - 1 - pageIndex;
uni.navigateBack({
delta: delta
});
} else {
// 页面栈中没有目标页面,重新打开
uni.navigateTo({
url: '/pages/target/target'
});
}
最佳实践
1. 统一管理路由
创建一个路由管理文件,集中管理所有页面路径:
javascript
// router.js
export default {
home: '/pages/index/index',
detail: '/pages/detail/detail',
user: '/pages/user/user',
// 带参数的路由方法
toDetail(id) {
return `/pages/detail/detail?id=${id}`;
}
}
使用时:
javascript
import router from '@/utils/router';
// 跳转到详情页
uni.navigateTo({
url: router.toDetail(123)
});
2. 避免频繁跳转
防止用户快速多次点击导致重复跳转:
javascript
let isNavigating = false;
function navigateTo(url) {
if (isNavigating) return;
isNavigating = true;
uni.navigateTo({
url: url,
complete: () => {
setTimeout(() => {
isNavigating = false;
}, 500);
}
});
}
3. 处理非法参数
在接收页面参数时进行验证:
javascript
export default {
onLoad(options) {
const id = options.id;
if (!id) {
uni.showToast({
title: '参数错误',
icon: 'none'
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
return;
}
// 正常业务逻辑
this.loadData(id);
}
}
常见问题
1. 页面栈溢出
当页面层级超过10层时,会出现无法继续跳转的情况。解决方法:
- 使用
redirectTo
替代navigateTo
- 使用
reLaunch
重置页面栈 - 优化页面结构,减少嵌套层级
2. 参数长度限制
URL参数有长度限制,过长的数据不适合通过URL传递。解决方法:
- 使用全局状态管理(Vuex/Pinia)
- 使用本地存储(uni.setStorage)
- 使用事件总线传递数据
3. 跨平台差异
不同平台对路由的实现有差异,需要注意:
- H5端支持直接修改
window.location
,但小程序和App不支持 - 小程序端页面栈最多10层,App端可能会更多
- 部分平台对URL长度有严格限制
总结
uni-app的路由系统虽然相对简单,但通过合理的封装和使用,可以满足大多数应用场景的需求。在实际开发中,应根据应用的复杂度选择合适的路由管理方式,并注意处理好页面间的数据传递和页面栈管理。