目录
- 前言
- 1. uni.navigateTo
- 2. uni.redirectTo
- 3. uni.reLaunch
- 4. uni.switchTab
- 5. uni.navigateBack
- 6. 页面和路由
- 7. 彩蛋
- 7.1 tabBar知识
- 7.2 EventChannel知识
- 7.3 总结
前言
在 UniApp 中,页面和路由是用于导航应用内不同页面的机制
UniApp 提供一系列 API 来实现页面间的跳转、重定向、重载、切换 Tab 页面以及返回上一个页面等操作
以下主要围绕基本的几个API接口做阐述,更多的可以参考官网:uni-app中的页面和路由
1. uni.navigateTo
跳转到应用内的某个非 tabBar 页面,可以携带参数
跳转的页面会被存入历史栈中,用户可以通过 uni.navigateBack 返回
参数说明:
url (String)
:跳转的目标页面路径,可以携带参数events (Object)
: 页面间通信使用的事件通道success (Function)
:接口调用成功的回调函数fail (Function)
: 接口调用失败的回调函数complete (Function)
:接口调用结束的回调函数
代码示例:
uni.navigateTo({url: '/pages/detail/detail?id=123', // 跳转页面路径,携带参数 id=123success: function() {console.log("跳转成功");},fail: function() {console.log("跳转失败");}
});
2. uni.redirectTo
关闭当前页面,跳转到应用内的某个非 tabBar 页面
新的页面不会被存入历史栈中,无法通过 uni.navigateBack 返回(中过一次坑,索性记住了)
参数说明:
url (String)
:目标页面路径success (Function)
: 成功回调fail (Function)
:失败回调complete (Function)
:完成回调
代码示例:
uni.redirectTo({url: '/pages/login/login', // 跳转到登录页面success: function() {console.log("重定向成功");},fail: function() {console.log("重定向失败");}
});
3. uni.reLaunch
关闭所有页面,重新打开应用内的某个页面
适用于需要彻底重启应用导航的场景,例如登录后重启整个应用
参数说明:
url (String)
:目标页面路径success (Function)
: 成功回调fail (Function)
:失败回调complete (Function)
:完成回调
uni.reLaunch({url: '/pages/home/home', // 重新打开首页success: function() {console.log("应用重启并跳转成功");},fail: function() {console.log("跳转失败");}
});
4. uni.switchTab
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
适用于应用含有多个 tabBar 页面时的导航
参数说明:
url (String)
:目标 tabBar 页面路径success (Function)
: 成功回调fail (Function)
:失败回调complete (Function)
:完成回调
uni.switchTab({url: '/pages/tab/home', // 跳转到 tabBar 页面的首页success: function() {console.log("切换 Tab 成功");},fail: function() {console.log("切换 Tab 失败");}
});
5. uni.navigateBack
关闭当前页面,返回上一层页面,支持传递返回的层级
参数说明:delta (Number)
返回的页面层级,默认值为 1,即返回上一层
uni.navigateBack({delta: 1, // 返回上一层页面success: function() {console.log("返回成功");},fail: function() {console.log("返回失败");}
});
6. 页面和路由
<template><view class="container"><button @click="goToDetail">跳转到详情页面</button><button @click="redirectToLogin">重定向到登录页面</button><button @click="switchToTab">切换到 Tab 页面</button><button @click="relaunchApp">重新启动应用并跳转</button></view>
</template><script>
export default {methods: {goToDetail() {uni.navigateTo({url: '/pages/detail/detail?id=456',success: () => {console.log('成功跳转到详情页');}});},redirectToLogin() {uni.redirectTo({url: '/pages/login/login',success: () => {console.log('成功重定向到登录页');}});},switchToTab() {uni.switchTab({url: '/pages/tab/home',success: () => {console.log('成功切换到 Tab 页面');}});},relaunchApp() {uni.reLaunch({url: '/pages/home/home',success: () => {console.log('成功重启应用并跳转');}});}}
}
</script>
详情页:
<template><view class="container"><text>这是详情页面,参数 ID 为 {{ id }}</text><button @click="goBack">返回上一页</button></view>
</template><script>
export default {data() {return {id: ''};},onLoad(options) {this.id = options.id; // 获取页面跳转时传递的参数},methods: {goBack() {uni.navigateBack({delta: 1, // 返回上一层success: () => {console.log('成功返回上一页');}});}}
}
</script>
7. 彩蛋
7.1 tabBar知识
在 UniApp 中,tabBar 页面和非 tabBar 页面是指不同类型的页面布局方式,具体体现在导航方式上
- tabBar 页面
应用底部带有 固定导航栏(即 tabBar)的页面,这种页面结构允许用户通过底部的导航栏在多个页面之间快速切换
tabBar 是 全局设置的,始终固定在应用的底部,并且通常包含多个页面的入口
主要特点有如下:
- 位置固定:tabBar 始终位于应用界面的底部,并且不可隐藏
- 快速切换:用户可以通过点击 tabBar 上的图标在不同页面间快速切换
- 互相独立:每个 tabBar 页面是相互独立的,切换时不会记录页面历史栈,无法通过
uni.navigateBack
返回之前的 tabBar 页面 - 全局配置:在 pages.json 文件中统一配置
示例配置 (pages.json):
{"tabBar": {"color": "#7A7E83","selectedColor": "#3cc51f","backgroundColor": "#ffffff","borderStyle": "black","list": [{"pagePath": "pages/home/home","text": "首页","iconPath": "static/home.png","selectedIconPath": "static/home_selected.png"},{"pagePath": "pages/user/user","text": "用户","iconPath": "static/user.png","selectedIconPath": "static/user_selected.png"}]}
}
list 数组定义 tabBar 上显示的页面(如首页、用户页面)
每个页面的 pagePath 必须对应应用中的实际页面路径
tabBar 页面切换示例:
uni.switchTab({url: '/pages/home/home',success: function() {console.log("成功切换到首页");}
});
- 非 tabBar 页面
非 tabBar 页面是指不属于底部导航栏的页面,这些页面一般通过其他页面跳转(例如 uni.navigateTo)进入
非 tabBar 页面可以被加入历史栈,允许用户返回之前访问的页面
主要特点有如下:
- 历史栈管理:非 tabBar 页面会记录在历史栈中,用户可以通过 uni.navigateBack 返回到前一个页面
- 自由跳转:这些页面通常用于展示详细内容、用户设置等不常用的页面,可以通过按钮、链接等进行跳转
- 没有固定导航栏:这些页面没有底部的导航栏(tabBar),也不会出现在全局导航中
非 tabBar 页面跳转示例:
uni.navigateTo({url: '/pages/detail/detail?id=123',success: function() {console.log('跳转成功');}
});
- 区别总结
特性 | tabBar 页面 | 非 tabBar 页面 |
---|---|---|
位置 | 带有底部的固定导航栏 | 没有固定导航栏 |
切换方式 | 通过 tabBar 快速切换,使用 uni.switchTab | 通过页面跳转,使用 uni.navigateTo、uni.redirectTo |
历史记录 | 不记录历史栈,不能通过 uni.navigateBack 返回 | 记录历史栈,可以通过 uni.navigateBack 返回 |
场景 | 常用于应用的主要页面(如首页、分类、个人中心) | 常用于详细页面或次要页面(如详情页、设置页面) |
使用建议
- tabBar 页面 适合放置应用的主导航页面,如首页、分类页、个人中心等核心功能页面,方便用户快速切换
- 非 tabBar 页面 适合用来展示详细内容、执行某些操作或提供额外功能
7.2 EventChannel知识
EventChannel 是 UniApp 提供的页面间通信机制,主要用于在页面跳转时传递复杂数据(如函数、对象等)和在跳转后保持页面之间的通信
例如,页面 A 跳转到页面 B 时,可以通过 EventChannel 传递消息,B 页面可以接收消息,并且可以在 B 页面处理后将数据返回给 A 页面
核心功能:
-
发送数据:通过
eventChannel.emit
方法发送数据到目标页面 -
接收数据:通过
eventChannel.on
方法在目标页面接收数据 -
获取 EventChannel:通过 getOpenerEventChannel 方法获取来源页面的 eventChannel
-
emit(eventName, data)
:发送数据到目标页面。
eventName (String):事件名称
data (Any):要发送的数据 -
on(eventName, callback)
: 监听并接收来自来源页面的数据
eventName (String):事件名称
callback (Function):事件触发时的回调,接收发送的数据 -
getOpenerEventChannel()
:获取来源页面的 EventChannel 对象
使用 EventChannel 的 Demo
- 页面 A:发送消息到页面 B
页面 A 跳转到页面 B,并通过 EventChannel 向 B 页面发送数据
B 页面处理后可以通过 EventChannel 返回数据
<template><view class="container"><button @click="goToDetail">跳转到详情页面并发送数据</button></view>
</template><script>
export default {methods: {goToDetail() {const that = this;uni.navigateTo({url: '/pages/detail/detail', // 跳转到详情页面events: {// 事件监听,等待详情页返回的数据acceptDataFromDetailPage: function(data) {console.log('接收到详情页返回的数据:', data);uni.showToast({title: `详情页返回数据: ${data}`,icon: 'none'});}},success: function (res) {// 通过 EventChannel 发送数据到详情页res.eventChannel.emit('sendDataToDetailPage', { id: 123, name: '张三' });}});}}
}
</script>
- 页面 B (detail.vue)
<template><view class="container"><text>这是详情页面</text><button @click="sendBack">返回上一页并传递数据</button></view>
</template><script>
export default {data() {return {id: '',name: ''};},onLoad() {// 获取来源页面的 EventChannelconst eventChannel = this.getOpenerEventChannel();// 监听来源页面发送的数据eventChannel.on('sendDataToDetailPage', (data) => {console.log('收到页面 A 传来的数据:', data);this.id = data.id;this.name = data.name;});},methods: {sendBack() {// 通过 EventChannel 向来源页面发送数据const eventChannel = this.getOpenerEventChannel();eventChannel.emit('acceptDataFromDetailPage', `数据已处理,ID 为 ${this.id}`);// 返回上一页uni.navigateBack();}}
}
</script>
具体逻辑如下:
当用户点击按钮时,页面 A 通过 uni.navigateTo 跳转到页面 B
跳转时,使用 events 属性定义了一个事件 acceptDataFromDetailPage,用于接收页面 B 的返回数据
在 success 回调中,使用 res.eventChannel.emit(‘sendDataToDetailPage’, …) 向 B 页面发送数据在页面 B:
使用 getOpenerEventChannel() 获取 A 页面的 EventChannel 对象
使用 eventChannel.on(‘sendDataToDetailPage’, …) 来接收 A 页面传来的数据,并将数据展示在页面上
点击按钮后,使用 eventChannel.emit(‘acceptDataFromDetailPage’, …) 将处理后的数据发送回页面 A,随后返回上一页
EventChannel 适用于需要在页面跳转过程中传递复杂数据或需要双向通信的场景
通过 emit 和 on 方法,页面间可以方便地进行数据的传递和处理
7.3 总结
navigateTo
,redirectTo
只能打开非 tabBar 页面switchTab
只能打开 tabBar 页面reLaunch
可以打开任意页面- 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar
- 不能在首页 onReady 之前进行页面跳转
- H5端页面刷新之后页面栈会消失,此时
navigateBack
不能返回,如果一定要返回可以使用history.back()
导航到浏览器的其他历史记录