UNPKG

gtht-miniapp-sdk

Version:

gtht-miniapp-sdk 是一套基于 Uniapp + Vue3 框架开发的兼容多端的 UI 组件库

116 lines (115 loc) 3.68 kB
import { URLQuery } from './url-query'; export class Router { status = 'idle'; guards = []; resolvePath(currentPath, path) { if (/^\//.test(path)) { return path; } const fragments = currentPath.replace(/\/[^/]+$/, '').split('/'); if (path.startsWith('./')) { path = path.slice(2); } fragments.push(...path.split('/')); const count = fragments.filter((frag) => frag === '..').length; for (let i = 0; i < count; i++) { const index = fragments.indexOf('..'); fragments.splice(index - 1, 2); } return '/' + fragments.join('/'); } parseQuery(url) { const [pathPart, queryPart] = url.split('?'); const pathQuery = { url: pathPart, }; if (queryPart) { pathQuery.query = Object.fromEntries(new URLQuery(queryPart)); } return pathQuery; } getPathQuery(currentPath, route) { const toRoute = typeof route === 'string' ? this.parseQuery(route) : this.parseQuery(route.url); return { url: this.resolvePath(currentPath, toRoute.url), query: { ...toRoute.query, ...(typeof route !== 'string' ? route.query : null), }, }; } makeUniRouteOptions(to, options) { const url = to.url + (Object.keys(to.query).length > 0 ? '?' + new URLQuery(Object.entries(to.query)).toString() : ''); return { ...options, url, }; } async intercept(options, action) { if (this.status === 'busy') { return; } this.status = 'busy'; const complete = options.complete; options.complete = (result) => { this.status = 'idle'; complete?.(result); }; const pages = getCurrentPages(); const currentPath = pages[pages.length - 1].route; const toPathQuery = this.getPathQuery(currentPath, { url: options.url, query: options.query, }); const fromPathQuery = { url: '/' + currentPath, query: {}, }; try { for (const guard of this.guards) { const result = await guard(toPathQuery, fromPathQuery); if (result === false) { this.status = 'idle'; return; } if (typeof result === 'string') { return action(this.makeUniRouteOptions(this.getPathQuery(currentPath, result), options)); } if (result !== null && typeof result === 'object') { return action(this.makeUniRouteOptions(this.getPathQuery(currentPath, result), options)); } } } catch (err) { this.status = 'idle'; console.error(err); return; } return action(this.makeUniRouteOptions(toPathQuery, options)); } navigateTo(options) { return this.intercept(options, uni.navigateTo); } redirectTo(options) { return this.intercept(options, uni.redirectTo); } reLaunch(options) { return this.intercept(options, uni.reLaunch); } switchTab(options) { return this.intercept(options, uni.switchTab); } navigateBack(options) { return uni.navigateBack(options); } beforeEach(guard) { if (!this.guards.includes(guard)) { this.guards.push(guard); } } }