1. uni-app路由基础概念
在uni-app中,路由系统是整个应用的核心导航机制,它决定了页面之间的跳转关系和页面栈的管理方式。与传统的Web路由不同,uni-app的路由需要兼顾多端兼容性,包括小程序、H5和App等不同平台的表现差异。
uni-app的路由配置主要通过pages.json文件实现,这个文件相当于应用的全局配置文件。每个页面路径都需要在这里预先声明,否则无法正常跳转。这种设计源于小程序平台的限制,但也在其他平台保持了统一性。
重要提示:uni-app的路由系统基于页面栈管理,最多支持10层页面栈(小程序平台限制),超过后将无法打开新页面。在实际开发中要特别注意页面深度的控制。
2. 页面配置与路由定义
2.1 pages.json基本结构
pages.json中的pages数组定义了应用的所有路由页面,数组第一项默认为应用启动页。每个页面配置包含两个主要属性:
json复制{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": true
}
},
{
"path": "pages/user/user",
"style": {
"navigationBarTitleText": "个人中心"
}
}
]
}
2.2 页面样式配置
每个页面的style节点可以覆盖globalStyle的全局配置,常用配置项包括:
navigationBarTitleText:导航栏标题文字内容navigationBarBackgroundColor:导航栏背景颜色enablePullDownRefresh:是否开启下拉刷新onReachBottomDistance:页面上拉触底距离
对于App平台特有的配置,可以放在app-plus节点下:
json复制{
"path": "pages/detail/detail",
"style": {
"app-plus": {
"titleNView": {
"buttons": [
{
"text": "分享"
}
]
}
}
}
}
3. 路由跳转与传参
3.1 路由跳转API
uni-app提供了多种路由跳转方式,对应不同的使用场景:
-
uni.navigateTo:保留当前页面,跳转到新页面
javascript复制uni.navigateTo({ url: '/pages/detail/detail?id=1' }) -
uni.redirectTo:关闭当前页面,跳转到新页面
javascript复制uni.redirectTo({ url: '/pages/login/login' }) -
uni.reLaunch:关闭所有页面,打开新页面
javascript复制uni.reLaunch({ url: '/pages/index/index' }) -
uni.switchTab:跳转到tabBar页面
javascript复制uni.switchTab({ url: '/pages/user/user' })
3.2 参数传递与接收
路由跳转时可以通过URL传参:
javascript复制// 跳转时传参
uni.navigateTo({
url: '/pages/detail/detail?id=1&name=test'
})
// 目标页面接收参数
export default {
onLoad(options) {
console.log(options.id) // 输出1
console.log(options.name) // 输出test
}
}
对于复杂对象参数,建议先序列化:
javascript复制const params = {id: 1, name: 'test'}
uni.navigateTo({
url: '/pages/detail/detail?data=' + encodeURIComponent(JSON.stringify(params))
})
4. 路由进阶应用
4.1 条件编译与路由
在多端开发中,可能需要为不同平台配置不同的路由行为:
javascript复制// #ifdef H5
uni.navigateTo({
url: '/pages/h5page/h5page'
})
// #endif
// #ifdef APP-PLUS
uni.navigateTo({
url: '/pages/apppage/apppage'
})
// #endif
4.2 路由拦截与权限控制
可以通过封装路由方法实现全局权限控制:
javascript复制// utils/router.js
const routeInterceptor = {
navigateTo(options) {
if (needLogin(options.url) && !isLogin()) {
uni.navigateTo({
url: '/pages/login/login'
})
return
}
uni.navigateTo(options)
}
}
export default routeInterceptor
4.3 动态路由处理
对于需要动态注册路由的场景,可以通过以下方式实现:
- 使用条件路由(condition):
json复制{
"condition": {
"current": 0,
"list": [
{
"name": "detail",
"path": "pages/detail/detail"
}
]
}
}
- 通过API动态修改:
javascript复制// 动态修改tabBar
uni.setTabBarItem({
index: 0,
text: '新首页'
})
5. 常见问题与解决方案
5.1 页面栈溢出问题
问题现象:当页面层级过深时,小程序平台会报错"页面栈超过10层"。
解决方案:
- 合理使用
redirectTo替代navigateTo - 对于不需要返回的场景使用
reLaunch - 使用
getCurrentPages()获取页面栈,必要时关闭中间页面
javascript复制const pages = getCurrentPages()
if (pages.length >= 10) {
uni.redirectTo({
url: '/pages/newpage/newpage'
})
} else {
uni.navigateTo({
url: '/pages/newpage/newpage'
})
}
5.2 路由参数丢失问题
问题现象:页面刷新后参数丢失。
解决方案:
- 对于H5端,可以使用本地存储暂存参数
- 对于App端,可以使用
plus.webview.currentWebview()获取参数 - 统一使用query参数传递关键标识,而非完整数据
5.3 tabBar页面跳转限制
问题现象:在tabBar页面中使用navigateTo跳转无效。
解决方案:
- 必须使用
switchTab跳转tabBar页面 - 对于需要带参数的跳转,可以使用全局变量或本地存储
- 或者使用自定义tabBar替代原生tabBar
6. 性能优化实践
6.1 路由预加载
在App平台可以使用preloadPage预加载页面:
javascript复制// 预加载页面
uni.preloadPage({
url: '/pages/detail/detail'
})
// 正式跳转时速度会更快
uni.navigateTo({
url: '/pages/detail/detail'
})
6.2 页面组件懒加载
对于复杂页面,可以使用easycom实现组件懒加载:
json复制{
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "@/components/uni-$1.vue"
}
}
}
6.3 页面缓存策略
通过合理配置页面缓存提高性能:
json复制{
"globalStyle": {
"renderingMode": "seperated"
},
"pages": [
{
"path": "pages/index/index",
"style": {
"app-plus": {
"bounce": "none",
"titleNView": false
}
}
}
]
}
在实际项目中,我发现合理使用onUnload生命周期释放资源也很重要:
javascript复制export default {
onUnload() {
// 清除定时器
// 取消事件监听
// 释放大内存对象
}
}
对于需要频繁跳转的页面,建议使用keep-alive策略(H5端):
html复制<template>
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</template>
通过以上这些实践,可以显著提升uni-app应用的路由性能和用户体验。记住,路由设计不仅关乎功能实现,更直接影响应用的整体架构和可维护性。
