UNPKG

vue-app-sdk

Version:
275 lines (274 loc) 7.99 kB
import { StorageOptions } from '../types'; import { NoopFn, SetRequired, Simplify } from '@rhao/types-base'; import { RouteLocationNormalized } from 'vue-router'; import { Plugin, PluginID } from './Plugin'; import { AppSDKInternalInstance } from './SDK'; /** * 路由导航方向 */ export declare enum NavigationDirection { /** * 前进 */ forward = "forward", /** * 后退 */ backward = "backward", /** * 刷新 */ unchanged = "unchanged" } /** * 路由配置项 */ export interface RouterOptions extends Omit<StorageOptions<true>, 'persistent'> { /** * 是否持久化详情记录,开启后会将 `detailsRecord` 存储在 `storage` 中,防止刷新丢失 * * ***注意:持久化后会缓存每次导航的详情信息,默认只在导航后退时清理旧导航信息,也可手动执行 `router.clearDetails()` 清理全部缓存。*** * @default true */ persistentDetails?: boolean; /** * 自定义识别导航方向 * @param to 目标路由 * @param from 来源路由 */ identifyDirection?: (ctx: { to: RouteLocationNormalized; from: RouteLocationNormalized; latestPosition: number | null; currentPosition: number | null; }) => NavigationDirection; } /** * Router Plugin ID */ export declare const ROUTER_ID: PluginID<Router>; /** * 路由详情 */ export interface RouteDetails<T = unknown> { /** * 来源路由信息 */ from: Simplify<Readonly<Pick<RouteLocationNormalized, 'path' | 'name' | 'fullPath' | 'hash'>>> | undefined; /** * 详情数据 */ data: T | undefined; } /** * 路由详情记录 */ export type RouteDetailsRecord = Record<string, RouteDetails>; /** * 获取路由详情(只读) * * @example * ```ts * // a.vue * router.pushWithData('/b', { msg: 'from a' }) * * // b.vue * import { useRouteDetails } from 'vue-app-sdk' * * const details = useRouteDetails() * details.data.msg // => 'from a' * * // 持续监听 * watch(() => details.data, (data) => { * console.log(data) * }) * ``` */ export declare function useRouteDetails<T = unknown>(): Readonly<import('vue').ShallowReactive<RouteDetails<T>>>; export type WatchDetailsFromKey = RouteLocationNormalized['path'] | RouteLocationNormalized['fullPath'] | RouteLocationNormalized['name']; export type WatchDetailsCallback<T = any> = (data: T | undefined, details: SetRequired<RouteDetails<T>, 'from'>) => void; /** * 精确监听路由详情,必须在组件 setup() 作用域内使用,将会在组件卸载前自动取消监听,支持手动取消 * @param fromKey 来源标识,支持路由的 `path`、`fullPath`、`name` * @param callback 监听回调 * @returns 取消监听回调 * * @example * ```ts * // a.vue * import { watchDetails } from 'vue-app-sdk' * * // 精确监听路由 `/b` 传递的消息 * watchDetails('/b', (data) => { * console.log(data.msg) // => 'from b' * }) * * router.pushWithData('/b', { msg: 'from a' }) * * // b.vue * import { useRouteDetails } from 'vue-app-sdk' * * const details = useRouteDetails() * details.data.msg // => 'from a' * * router.backWithData({ msg: 'from b' }) * ``` */ export declare function watchDetails<T = unknown>(fromKey: WatchDetailsFromKey, callback: WatchDetailsCallback<T>): () => void; /** * 路由插件 */ export declare class Router implements Plugin { /** * 配置项 */ options: RouterOptions; constructor( /** * 配置项 */ options?: RouterOptions); id: PluginID<Router>; /** * 最近记录的位置 */ latestPosition: number | null; /** * 识别导航方向 * @readonly */ get identifyDirection(): (ctx: { to: RouteLocationNormalized; from: RouteLocationNormalized; latestPosition: number | null; currentPosition: number | null; }) => NavigationDirection; /** * 路由详情记录 */ private _detailsRecord; /** * 是否正在导航 */ private _isNavigating; /** * 锁定 `beforeOnce` */ private _onceLocked; /** * 详情数据 */ private _detailsData; /** * 设置详情数据 * @param data 详情数据 */ private _setDetailsData; /** * 消费详情数据 */ private _consumeDetailsData; /** * 更新详情记录 * @param value 详情记录 */ private _updateDetailsRecord; /** * 获取路由详情 * @param fullPath 完整路径 * @returns 路由详情 */ getDetails: (fullPath: string) => RouteDetails<unknown>; /** * 清理所有详情记录 */ clearDetailsRecord: () => void; /** * 创建路由详情 * @param details 需要合并的路由详情 * @param increment 需要自增路由详情变更次数 */ makeDetails: (details?: Partial<RouteDetails>, increment?: boolean) => RouteDetails; /** * 获取当前导航位置 * @returns 当前导航位置 */ getCurrentPosition: () => number | null; install: (sdk: AppSDKInternalInstance) => () => void; } declare module 'vue-app-sdk' { interface AppSDKHooks { /** * 路由前进后触发 */ 'sdk:router:forward'(to: RouteLocationNormalized, from: RouteLocationNormalized): void; /** * 路由后退后触发 */ 'sdk:router:backward'(to: RouteLocationNormalized, from: RouteLocationNormalized): void; /** * 路由替换后触发 */ 'sdk:router:replace'(to: RouteLocationNormalized, from: RouteLocationNormalized): void; /** * 路由导航成功后触发 */ 'sdk:router:navigate'(direction: NavigationDirection, to: RouteLocationNormalized, from: RouteLocationNormalized): void; /** * 路由详情记录变更后触发 */ 'sdk:router:detailsRecordChange'(record: RouteDetailsRecord): void; } } declare module 'vue-router' { interface Router { /** * 是否正在导航 */ readonly isNavigating: boolean; /** * 同 `router.beforeEach`,区别在于仅单次触发,直到 `afterEach` 被执行后可下次触发,常用于避免在 `beforeEach` 内重定向再次触发 `beforeEach` 钩子的回调处理 */ beforeOnce(guard: NavigationGuard): NoopFn; /** * 携带跨页面数据,类似于 `params` * @example * ```ts * // a.vue * router.pushWithData('/b', { msg: 'from a' }) * * // b.vue * import { useRouteDetails } from 'vue-app-sdk' * * const details = useRouteDetails() * details.data.msg // => 'from a' * * // 持续监听 * watch(() => details.data, (data) => { * console.log(data.msg) * }) * ``` */ pushWithData(to: RouteLocationRaw, data?: unknown): ReturnType<Router['push']>; /** * 携带跨页面数据,类似于 `params`,参考 `router.pushWithData` */ replaceWithData(to: RouteLocationRaw, data?: unknown): ReturnType<Router['replace']>; /** * 携带跨页面数据,类似于 `params`,参考 `router.pushWithData` */ forwardWithData(data?: unknown): ReturnType<Router['forward']>; /** * 携带跨页面数据,类似于 `params`,参考 `router.pushWithData` */ backWithData(data?: unknown): ReturnType<Router['back']>; /** * 携带跨页面数据,类似于 `params`,参考 `router.pushWithData` */ goWithData(delta: number, data?: unknown): ReturnType<Router['go']>; /** * 清理所有详情记录 */ clearDetailsRecord(): void; } }