bsl
Version:
基于React的框架和UI组件
101 lines (89 loc) • 2.62 kB
text/typescript
import { History } from 'history';
import BSL from '../typings';
import PageComponent from './PageComponent';
interface AppData {
pages: PageComponent<any, any>[];
scrollLocation: number[];
history: History | undefined;
inputFoucs: boolean;
env: BSL.Env;
currentPageId: number;
}
export interface AppBaseProps {
/** 路由改变时触发 */
onRouteChange?: (pathname: string) => void;
children: any;
}
export interface AppProps extends AppBaseProps, BSL.PageProps<{}> {
history: History;
}
/** 应用运行时的数据 */
const appData: AppData = {
/** 储存页面 */
pages: [],
/** 离开页面时记录的滚动条位置 */
scrollLocation: [],
/** react-router传递下来的history */
history: undefined,
/** 是否处于input foucs状态,用于解决中文输入的BUG */
inputFoucs: false,
/** 运行时的环境变量 */
env: process.env.NODE_ENV as BSL.Env,
/** 当前页面id */
currentPageId: 1
};
/* 获取上N个页面的类声明 */
function getPrevPageClassDeclaration<P = {}, S = {}>(prevCount: number): PageComponent<P, S> | undefined {
return appData.pages[appData.pages.length - prevCount];
}
/** 是否是replace动作 */
function isReplaceAction(nextProps: AppProps): boolean {
const action = nextProps.history.action;
const isReplace = action === 'REPLACE';
return isReplace;
}
/** 添加一个页面 */
function push(nextProps: AppProps): void {
const currentPage = getPrevPageClassDeclaration(1)!;
// 页面的进入事件
if (currentPage?.pageEnter) {
currentPage.pageEnter();
}
if (currentPage?.pageActive) {
currentPage.pageActive();
}
window.scrollTo(0, 0);
}
/** 卸载一个页面 */
function pop(nextProps: AppProps): void {
const top = appData.scrollLocation[appData.scrollLocation.length - 1];
const currentPage = getPrevPageClassDeclaration(1)!;
// 页面的离开事件
if (currentPage?.pageLeave) {
currentPage.pageLeave();
}
if (currentPage?.pageActive) {
currentPage.pageActive();
}
if (appData.pages.length && !isReplaceAction(nextProps)) {
const toPage = getPrevPageClassDeclaration(2);
// 目标页面的进入事件
if (toPage) {
// 后退回页面时,重置进入时间
toPage.entrytime = Date.now();
}
}
appData.pages.pop();
appData.scrollLocation.pop();
appData.currentPageId--;
setTimeout(() => {
window.scrollTo(0, top);
});
}
export {
appData,
getPrevPageClassDeclaration,
isReplaceAction,
push,
pop
};