98 lines
2.3 KiB
JavaScript
98 lines
2.3 KiB
JavaScript
// frontend/utils/preloadApi/navigate.js
|
||
// 包装 uni.navigateTo / switchTab / reLaunch
|
||
// 跳转前 fire-and-forget 预拉目标页数据,不 await
|
||
|
||
import { prefetchFor } from './core'
|
||
|
||
/**
|
||
* 从 URL 中解析 query string → params 对象
|
||
* 例:'/pages/foo/bar?id=123&type=hot' → { id: '123', type: 'hot' }
|
||
*/
|
||
function parseQueryParams(url) {
|
||
const idx = url.indexOf('?')
|
||
if (idx === -1) return {}
|
||
|
||
const qs = url.substring(idx + 1)
|
||
const params = {}
|
||
// 使用 URLSearchParams(uniapp 环境支持)
|
||
try {
|
||
const usp = new URLSearchParams(qs)
|
||
for (const [k, v] of usp) {
|
||
// URLSearchParams 已自动解码,不需要再 decodeURIComponent
|
||
params[k] = v
|
||
}
|
||
} catch (e) {
|
||
// fallback:手动解析
|
||
for (const pair of qs.split('&')) {
|
||
const eqIdx = pair.indexOf('=')
|
||
if (eqIdx === -1) continue
|
||
const k = decodeURIComponent(pair.substring(0, eqIdx))
|
||
const v = decodeURIComponent(pair.substring(eqIdx + 1))
|
||
if (k) params[k] = v
|
||
}
|
||
}
|
||
return params
|
||
}
|
||
|
||
/**
|
||
* 从 URL 中提取目标页路径(去掉 query string)
|
||
*/
|
||
function extractPath(url) {
|
||
const idx = url.indexOf('?')
|
||
return idx === -1 ? url : url.substring(0, idx)
|
||
}
|
||
|
||
/**
|
||
* 替代 uni.navigateTo
|
||
* 内部:解析目标页 → 触发预拉(fire-and-forget)→ 立即跳转
|
||
*/
|
||
export function navigateTo(opts) {
|
||
const url = typeof opts === 'string' ? opts : opts.url
|
||
const targetPath = extractPath(url)
|
||
const params = parseQueryParams(url)
|
||
|
||
// 触发预拉(fire-and-forget,不 await)
|
||
prefetchFor(targetPath, params)
|
||
|
||
// 立即跳转
|
||
if (typeof opts === 'string') {
|
||
uni.navigateTo({ url: opts })
|
||
} else {
|
||
uni.navigateTo(opts)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 替代 uni.switchTab
|
||
*/
|
||
export function switchTab(opts) {
|
||
const url = typeof opts === 'string' ? opts : opts.url
|
||
const targetPath = extractPath(url)
|
||
const params = parseQueryParams(url)
|
||
|
||
prefetchFor(targetPath, params)
|
||
|
||
if (typeof opts === 'string') {
|
||
uni.switchTab({ url: opts })
|
||
} else {
|
||
uni.switchTab(opts)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 替代 uni.reLaunch
|
||
*/
|
||
export function reLaunch(opts) {
|
||
const url = typeof opts === 'string' ? opts : opts.url
|
||
const targetPath = extractPath(url)
|
||
const params = parseQueryParams(url)
|
||
|
||
prefetchFor(targetPath, params)
|
||
|
||
if (typeof opts === 'string') {
|
||
uni.reLaunch({ url: opts })
|
||
} else {
|
||
uni.reLaunch(opts)
|
||
}
|
||
}
|