| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- /**
- * 全局导航工具函数
- * 统一管理页面跳转和返回逻辑
- */
- /**
- * 返回处理
- * 检查页面栈,如果是首页则跳转到主页,否则返回上一页
- * @param {Object} options 配置选项
- * @param {string} options.fallbackUrl 当无法返回时的跳转地址,默认为首页
- * @param {boolean} options.showLog 是否显示调试日志,默认为true
- */
- export const goBack = (options = {}) => {
- const {
- fallbackUrl = '/pages/main/index?tab=my',
- showLog = true
- } = options
- const pages = getCurrentPages()
-
- if (showLog) {
- console.log('当前页面栈长度:', pages.length)
- console.log('页面栈信息:', pages.map(page => page.route))
- }
-
- if (pages.length <= 1) {
- // 如果是首页,跳转到指定页面
- if (showLog) {
- console.log('当前是首页,跳转到:', fallbackUrl)
- }
- uni.reLaunch({
- url: fallbackUrl
- })
- } else {
- // 有上一页,正常返回
- if (showLog) {
- console.log('返回上一页')
- }
- uni.navigateBack()
- }
- }
- /**
- * 跳转处理
- * 根据目标页面类型选择合适的跳转方式
- * @param {string} url 目标页面路径
- * @param {Object} options 配置选项
- * @param {string} options.type 跳转类型:'navigate'|'redirect'|'reLaunch'|'switchTab'|'auto'
- * @param {boolean} options.showLog 是否显示调试日志,默认为true
- */
- export const goTo = (url, params = {}, options = {}) => {
- const {
- type = 'auto',
- showLog = true
- } = options
- // 构建完整的URL(包含参数)
- let fullUrl = url
- if (params && Object.keys(params).length > 0) {
- const queryString = Object.keys(params)
- .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
- .join('&')
- fullUrl = `${url}?${queryString}`
- }
- if (showLog) {
- console.log('智能跳转到:', fullUrl, '类型:', type, '参数:', params)
- }
- // 使用配置中的 tabbar 页面列表(当前为空,避免误判)
- const tabbarPages = navigationConfig?.tabbarPages || []
- // 自动判断跳转类型
- if (type === 'auto') {
- // 如果跳到主容器,使用 reLaunch 支持带参数刷新
- if (url.startsWith('/pages/main/index')) {
- uni.reLaunch({ url: fullUrl })
- } else if (tabbarPages.includes(url)) {
- // 理论上当前为空,不会进入
- uni.switchTab({ url })
- } else {
- uni.navigateTo({ url: fullUrl })
- }
- } else {
- // 使用指定的跳转类型
- switch (type) {
- case 'navigate':
- uni.navigateTo({ url: fullUrl })
- break
- case 'redirect':
- uni.redirectTo({ url: fullUrl })
- break
- case 'reLaunch':
- uni.reLaunch({ url: fullUrl })
- break
- case 'switchTab':
- uni.switchTab({ url }) // switchTab不支持参数
- break
- default:
- console.warn('未知的跳转类型:', type)
- uni.navigateTo({ url: fullUrl })
- }
- }
- }
- /**
- * 跳到主容器指定tab
- * @param {string} tabKey e.g. 'my' | 'todo' | 'statistics'
- */
- export const goToMainTab = (tabKey = 'my') => {
- const url = `/pages/main/index?tab=${encodeURIComponent(tabKey)}`
- uni.reLaunch({ url })
- }
- /**
- * 获取当前页面信息
- * @returns {Object} 当前页面信息
- */
- export const getCurrentPageInfo = () => {
- const pages = getCurrentPages()
- const currentPage = pages[pages.length - 1]
-
- return {
- route: currentPage?.route || '',
- options: currentPage?.options || {},
- stackLength: pages.length,
- isFirstPage: pages.length <= 1
- }
- }
- /**
- * 检查是否为tabbar页面
- * @param {string} url 页面路径
- * @returns {boolean} 是否为tabbar页面
- */
- export const isTabbarPage = (url) => {
- const tabbarPages = navigationConfig?.tabbarPages || []
-
- // 处理相对路径和绝对路径
- const normalizedUrl = url.startsWith('/') ? url : `/${url}`
- return tabbarPages.includes(normalizedUrl)
- }
- /**
- * 安全的页面跳转
- * 在跳转前检查页面栈,避免栈溢出
- * @param {string} url 目标页面路径
- * @param {Object} options 配置选项
- * @param {number} options.maxStackSize 最大页面栈大小,默认为10
- * @param {boolean} options.showLog 是否显示调试日志,默认为true
- */
- export const safeNavigate = (url, options = {}) => {
- const {
- maxStackSize = 10,
- showLog = true
- } = options
- const pages = getCurrentPages()
-
- if (showLog) {
- console.log('安全跳转检查,当前栈大小:', pages.length, '最大栈大小:', maxStackSize)
- }
- if (pages.length >= maxStackSize) {
- // 页面栈过深,使用redirectTo替换当前页面
- if (showLog) {
- console.log('页面栈过深,使用redirectTo替换当前页面')
- }
- uni.redirectTo({ url })
- } else {
- // 正常跳转
- goTo(url, { showLog })
- }
- }
- /**
- * 返回到指定页面
- * @param {string} targetRoute 目标页面路由
- * @param {Object} options 配置选项
- * @param {string} options.fallbackUrl 找不到目标页面时的跳转地址
- * @param {boolean} options.showLog 是否显示调试日志,默认为true
- */
- export const backToPage = (targetRoute, options = {}) => {
- const {
- fallbackUrl = '/pages/main/index?tab=my',
- showLog = true
- } = options
- const pages = getCurrentPages()
-
- // 查找目标页面在栈中的位置
- let targetIndex = -1
- for (let i = pages.length - 1; i >= 0; i--) {
- if (pages[i].route === targetRoute) {
- targetIndex = i
- break
- }
- }
- if (targetIndex >= 0) {
- // 找到目标页面,计算需要返回的层数
- const delta = pages.length - 1 - targetIndex
- if (showLog) {
- console.log('返回到页面:', targetRoute, '需要返回', delta, '层')
- }
- uni.navigateBack({ delta })
- } else {
- // 没找到目标页面,跳转到指定页面
- if (showLog) {
- console.log('未找到目标页面:', targetRoute, '跳转到:', fallbackUrl)
- }
- uni.reLaunch({ url: fallbackUrl })
- }
- }
- /**
- * 导航工具的默认配置
- */
- export const navigationConfig = {
- // 默认的fallback页面
- defaultFallbackUrl: '/pages/main/index?tab=my',
- // 是否显示调试日志
- showLog: true,
- // 最大页面栈大小
- maxStackSize: 10,
- // tabbar页面列表
- tabbarPages: [
- // 当前项目未使用原生tabBar,保留空数组避免误判
- ]
- }
- // 导出默认对象,方便统一导入
- export default {
- goBack,
- goTo,
- goToMainTab,
- getCurrentPageInfo,
- isTabbarPage,
- safeNavigate,
- backToPage,
- navigationConfig
- }
|