vue-app-sdk
Version:
275 lines (274 loc) • 7.99 kB
TypeScript
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;
}
}