import { onLoad } from "@dcloudio/uni-app"; const useTransferPage = () => { const funcMap = { redirect: uni.redirectTo, reLaunch: uni.reLaunch, switchTab: uni.switchTab }; let prevData = ref>({}); let transferResolver: ((value: unknown) => void) | null = null; let eventChannel: UniApp.EventChannel | null = null; // onMounted(() => { // 使用instance获取getOpenerEventChannel在非页面级组件中会报错 // const instance = getCurrentInstance().proxy // if (instance) { // eventChannel = instance.getOpenerEventChannel(); // } // }); type Callback = (() => void) | null; type TransferOptions = { data?: Record | null, type?: string, bigData?: Record | null, callback?: Callback } onLoad((opt) => { const pages = getCurrentPages(); const page = pages[pages.length - 1]; eventChannel = (page as any).getOpenerEventChannel(); emit('onPageOpen'); for (const key in opt) { if (opt.hasOwnProperty(key) && !['data', 'storageKey'].includes(key)) { prevData.value[key] = decodeURIComponent(opt[key]); } } if (!opt) return; let originData = opt.data; if (opt.data) { if (opt.data.startsWith('%257B')) { originData = decodeURIComponent(opt.data); } const data = JSON.parse(decodeURIComponent(originData || '{}')); Object.assign(prevData.value, data); } const storageKey = opt.storageKey; if (storageKey) { const storageData = uni.getStorageSync(storageKey); Object.assign(prevData.value, storageData); } }); function getTransferUrl(url: string, data: any, bigData: any) { const urlParams = { data: data ? encodeURIComponent(JSON.stringify(data)) : null, storageKey: bigData ? 'transferBigData' : null }; // 处理URL中已存在的参数 const [baseUrl, existingQuery] = url.split('?'); const existingParams = {}; // 解析现有参数 if (existingQuery) { existingQuery.split('&').forEach(param => { const [key, value] = param.split('='); if (key) { // 为 existingParams 显式声明类型为 Record (existingParams as Record)[key] = value; } }); } // 合并新参数 Object.entries(urlParams) .filter(([_, value]) => value) .forEach(([key, value]) => { (existingParams as Record)[key] = value as string; }); // 构建查询字符串 const queryString = Object.entries(existingParams) .map(([key, value]) => `${key}=${value}`) .join('&'); return queryString ? `${baseUrl}?${queryString}` : baseUrl; } function transferTo(url: string, { data = null, type = 'navigate', bigData = null, callback = null }: TransferOptions = {}) { return new Promise((resolve, reject) => { transferResolver = resolve; if (bigData) { uni.setStorageSync('transferBigData', bigData); } else { // clear big data by force uni.removeStorageSync('transferBigData'); } const nextUrl = getTransferUrl(url, data, bigData); if (type === 'navigate') { uni.navigateTo({ url: nextUrl, events: { transferEnd: (data: any) => { transferResolver?.(data); }, onPageOpen: () => { if (callback) { callback?.(); } } }, fail: (err) => { console.log('transferTo fail', err); } }); } else { const routeFunc = funcMap[type as keyof typeof funcMap]; routeFunc({ url: nextUrl, fail: (err) => { console.log('transferTo fail', err); reject(err); } }); } }); } function transferBack(data:any = null, delta = 1) { emit('transferEnd', data); // force clear big data uni.removeStorageSync('transferBigData'); const pages = getCurrentPages(); if (pages.length === 1) { switchTab('/pages/splash/splash'); } else { uni.navigateBack({ delta: delta, success: () => { }, fail: (err) => { switchTab('/pages/splash/splash'); } }); } } function switchTab(url: string) { uni.switchTab({ url: url, fail: (err) => { console.log(err); } }); } function emit(event: string, data = null) { if (eventChannel?.emit) { eventChannel.emit(event, data); } else { console.warn('上级页面丢失,无法触发transferEnd'); } } return { prevData, transferTo, transferBack, } }; export default useTransferPage;