/** * 页面导航工具函数 * 统一处理小程序内的各种跳转逻辑 */ /** * TabBar 页面路径列表 * 这些页面需要使用 switchTab 而不是 navigateTo */ export const TABBAR_PAGES = [ '/pages/index/index', '/pages/message/index', '/pages/mine/index' ] /** * 链接类型枚举 */ export const LINK_TYPE = { /** 内部页面 */ INTERNAL: 1, /** 外部链接(H5) */ EXTERNAL: 2, /** 其他小程序 */ MINI_PROGRAM: 3 } /** * 判断是否为 TabBar 页面 * @param {string} url - 页面路径 * @returns {boolean} */ export function isTabBarPage(url) { return TABBAR_PAGES.includes(url) } /** * 统一页面跳转函数 * 根据链接类型自动选择合适的跳转方式 * * @param {string} url - 跳转地址 * @param {number} linkType - 链接类型:1=内部页面, 2=外部链接, 3=小程序 * @param {Object} options - 额外配置 * @param {Function} options.onFail - 跳转失败回调 * @param {Function} options.onSuccess - 跳转成功回调 */ export function navigateToPage(url, linkType = LINK_TYPE.INTERNAL, options = {}) { if (!url) { console.warn('[navigate] url 为空,跳过跳转') return } const { onFail, onSuccess } = options switch (linkType) { case LINK_TYPE.EXTERNAL: // 外部链接:复制到剪贴板(小程序限制无法直接打开外部链接) handleExternalLink(url) break case LINK_TYPE.MINI_PROGRAM: // 跳转其他小程序 handleMiniProgramLink(url, { onFail, onSuccess }) break case LINK_TYPE.INTERNAL: default: // 内部页面跳转 handleInternalLink(url, { onFail, onSuccess }) break } } /** * 处理内部页面跳转 * 自动判断是否为 TabBar 页面 * * @param {string} url - 页面路径 * @param {Object} callbacks - 回调函数 */ function handleInternalLink(url, { onFail, onSuccess } = {}) { const navigateMethod = isTabBarPage(url) ? uni.switchTab : uni.navigateTo navigateMethod({ url, success: () => { onSuccess && onSuccess() }, fail: (err) => { console.error('[navigate] 页面跳转失败:', url, err) if (onFail) { onFail(err) } else { uni.showToast({ title: '页面跳转失败', icon: 'none' }) } } }) } /** * 处理外部链接 * 由于小程序限制,外部链接只能复制到剪贴板 * * @param {string} url - 外部链接地址 */ function handleExternalLink(url) { uni.setClipboardData({ data: url, success: () => { uni.showToast({ title: '链接已复制', icon: 'success' }) }, fail: () => { uni.showToast({ title: '复制失败', icon: 'none' }) } }) } /** * 处理小程序跳转 * URL 格式:appId:path(path 可选) * * @param {string} url - 格式为 "appId:path" 的字符串 * @param {Object} callbacks - 回调函数 */ function handleMiniProgramLink(url, { onFail, onSuccess } = {}) { const [appId, path] = url.split(':') if (!appId) { console.error('[navigate] 小程序 appId 为空') uni.showToast({ title: '跳转配置错误', icon: 'none' }) return } uni.navigateToMiniProgram({ appId, path: path || '', success: () => { onSuccess && onSuccess() }, fail: (err) => { console.error('[navigate] 跳转小程序失败:', appId, err) if (onFail) { onFail(err) } else { uni.showToast({ title: '跳转失败', icon: 'none' }) } } }) } /** * 跳转到 WebView 页面 * 用于在小程序内打开 H5 页面 * * @param {string} url - H5 页面地址 */ export function navigateToWebView(url) { if (!url) return uni.navigateTo({ url: `/pages/webview/index?url=${encodeURIComponent(url)}` }) } /** * 返回上一页 * @param {number} delta - 返回的页面数,默认 1 */ export function navigateBack(delta = 1) { uni.navigateBack({ delta }) } /** * 重定向到指定页面(关闭当前页) * @param {string} url - 页面路径 */ export function redirectTo(url) { if (!url) return if (isTabBarPage(url)) { uni.switchTab({ url }) } else { uni.redirectTo({ url }) } }