201 lines
4.2 KiB
JavaScript
201 lines
4.2 KiB
JavaScript
/**
|
||
* 页面导航工具函数
|
||
* 统一处理小程序内的各种跳转逻辑
|
||
*/
|
||
|
||
/**
|
||
* 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 })
|
||
}
|
||
}
|