vue-app-sdk
Version:
166 lines (165 loc) • 4.6 kB
TypeScript
import { Awaitable } from '@rhao/types-base';
import { MaybeRefOrGetter } from 'vue';
import { AppSDKInternalInstance, Plugin, PluginID, NavigationDirection } from '../..';
import { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router';
/**
* Scroll position similar to
* {@link https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions | `ScrollToOptions`}.
* Note that not all browsers support `behavior`.
*/
export interface ScrollPositionCoordinates {
behavior?: ScrollOptions['behavior'];
left?: number;
top?: number;
}
export type ScrollPositionCoordinatesGroup = Record<string, ScrollPositionCoordinates>;
export interface RouterScrollHandlerContext {
/**
* 目标路由
*/
to: RouteLocationNormalized;
/**
* 来源路由,手动触发时同目标路由一致
*/
from: RouteLocationNormalizedLoaded;
/**
* 滚动元素
*/
element: Element | Window;
/**
* 选择器
*/
selector: string;
/**
* 导航方向,手动滚动时为 `unchanged`
*/
direction: NavigationDirection;
/**
* 已保存的滚动位置
*/
savedPosition: ScrollPositionCoordinates | undefined;
/**
* 是否手动触发
*/
isManual: boolean;
}
export interface RouterScrollHandler {
(context: RouterScrollHandlerContext): Awaitable<ScrollPositionCoordinates | boolean | void>;
}
export interface RouterScrollerOptions {
/**
* 是否自动收集滚动位置
* @default true
*/
autoCollect?: MaybeRefOrGetter<boolean>;
/**
* 允许捕获的选择器,支持特殊选择器 `window`、`body`
*/
selectors: Record<string, boolean | RouterScrollHandler>;
/**
* 默认的滚动行为
*/
behavior?: ScrollOptions['behavior'];
/**
* `selectors` 为 `true` 时默认将在导航成功后还原滚动位置,如果设为 `true` 则仅在导航后退时还原,适用于移动端
* @default false
*/
scrollOnlyBackward?: boolean;
}
/**
* RouterScroller Plugin ID
*/
export declare const ROUTER_SCROLLER_ID: PluginID<RouterScroller>;
/**
* 路由滚动管理插件
*/
export declare class RouterScroller implements Plugin {
/**
* 配置项
*/
options: RouterScrollerOptions;
constructor(
/**
* 配置项
*/
options: RouterScrollerOptions);
id: PluginID<RouterScroller>;
/**
* AppSDK 实例
*/
private _sdk;
/**
* 滚动位置记录
*/
positions: Map<string, ScrollPositionCoordinatesGroup>;
/**
* 是否自动模式
*/
private _isAuto;
/**
* 是否自动模式
* @readonly
*/
get isAuto(): boolean;
/**
* 切换自动模式
* @param value 状态值
*/
toggleAuto: (value?: boolean) => boolean;
/**
* 启用自动模式
*/
enableAuto: () => boolean;
/**
* 禁用自动模式
*/
disableAuto: () => boolean;
/**
* 由于 `Transition` 动画可能导致元素自动还原滚动无效,此时可手动触发还原滚动
* @example
* ```html
* <script setup lang="ts">
* import { useAppSDK, ROUTER_SCROLLER_ID } from 'vue-app-sdk'
*
* const routerScroller = useAppSDK().getPlugin(ROUTER_SCROLLER_ID)!
*
* function handleAfterEnter() {
* routerScroller.trigger()
* }
* </script>
*
* <template>
* <Transition @after-enter="handleAfterEnter">
* ...
* </Transition>
* </template>
* ```
*/
trigger: () => Promise<void>;
/**
* 获取滚动元素
* @param selector 选择器
* @returns 滚动元素
*/
querySelector: (selector: string) => (Window & typeof globalThis) | Element | null | undefined;
/**
* 获取滚动位置
* @param el 滚动元素
* @returns 滚动位置
*/
getScrollPosition: (el: Element | Window) => ScrollPositionCoordinates;
/**
* 捕获滚动位置
*/
capturePositions: () => ScrollPositionCoordinatesGroup;
/**
* 还原滚动位置
* @param to 目标路由
* @param from 来源路由
* @param position 滚动位置
* @param direction 导航方向
* @param isManual 是否手动触发
*/
applyPositions: (to: RouteLocationNormalized, from: RouteLocationNormalizedLoaded, position: ScrollPositionCoordinatesGroup | undefined, direction: NavigationDirection, isManual?: boolean) => Promise<void>;
install: (sdk: AppSDKInternalInstance) => void;
}