fix(vue): using router.go now shows correct view (#23773)

resolves #22563
This commit is contained in:
Liam DeBeasi
2021-08-17 08:53:55 -04:00
committed by GitHub
parent 6b18a89ac2
commit 621f4faa1a
10 changed files with 403 additions and 42 deletions

View File

@ -18,7 +18,7 @@ import {
import { AnimationBuilder } from '@ionic/vue';
export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) => {
let currentNavigationInfo: NavigationInformation = { direction: undefined, action: undefined };
let currentNavigationInfo: NavigationInformation = { direction: undefined, action: undefined, delta: undefined };
/**
* Ionic Vue should only react to navigation
@ -32,7 +32,7 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
router.afterEach((to: RouteLocationNormalized, _: RouteLocationNormalized, failure?: NavigationFailure) => {
if (failure) return;
const { direction, action } = currentNavigationInfo;
const { direction, action, delta } = currentNavigationInfo;
/**
* When calling router.replace, we are not informed
@ -42,13 +42,26 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
* We need to use opts.history rather than window.history
* because window.history will be undefined when using SSR.
*/
const replaceAction = opts.history.state.replaced ? 'replace' : undefined;
handleHistoryChange(to, action || replaceAction, direction);
currentNavigationInfo = { direction: undefined, action: undefined };
currentHistoryPosition = opts.history.state.position as number;
const replaceAction = opts.history.state.replaced ? 'replace' : undefined;
handleHistoryChange(to, action || replaceAction, direction, delta);
currentNavigationInfo = { direction: undefined, action: undefined, delta: undefined };
});
const locationHistory = createLocationHistory();
/**
* Keeping track of the history position
* allows us to determine if a user is pushing
* new pages or updating history via the forward
* and back browser buttons.
*/
const initialHistoryPosition = opts.history.state.position as number;
let currentHistoryPosition = opts.history.state.position as number;
let currentRouteInfo: RouteInfo;
let incomingRouteParams: RouteParams;
let currentTab: string | undefined;
@ -78,14 +91,21 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
* router.beforeEach
*/
currentNavigationInfo = {
action: info.type,
delta: info.delta,
/**
* Both the browser forward and backward actions
* are considered "pop" actions, but when going forward
* we want to make sure the forward animation is used.
*/
action: (info.type === 'pop' && info.delta >= 1) ? 'push' : info.type,
direction: info.direction === '' ? 'forward' : info.direction
};
});
const handleNavigateBack = (defaultHref?: string, routerAnimation?: AnimationBuilder) => {
// todo grab default back button href from config
const routeInfo = locationHistory.current();
const routeInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition);
if (routeInfo && routeInfo.pushedByRoute) {
const prevInfo = locationHistory.findLastLocation(routeInfo);
if (prevInfo) {
@ -131,16 +151,23 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
}
// TODO RouteLocationNormalized
const handleHistoryChange = (location: any, action?: RouteAction, direction?: RouteDirection) => {
const handleHistoryChange = (
location: any,
action?: RouteAction,
direction?: RouteDirection,
delta?: number
) => {
let leavingLocationInfo: RouteInfo;
if (incomingRouteParams) {
if (incomingRouteParams.routerAction === 'replace') {
leavingLocationInfo = locationHistory.previous();
} else if (incomingRouteParams.routerAction === 'pop') {
leavingLocationInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition + 1);
} else {
leavingLocationInfo = locationHistory.current();
leavingLocationInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition - 1);
}
} else {
leavingLocationInfo = locationHistory.current();
leavingLocationInfo = currentRouteInfo;
}
if (!leavingLocationInfo) {
@ -160,9 +187,10 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
tab: currentTab
}
} else if (action === 'pop') {
const routeInfo = locationHistory.current();
const routeInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition - delta);
if (routeInfo && routeInfo.pushedByRoute) {
const prevRouteInfo = locationHistory.findLastLocation(routeInfo);
const prevRouteInfo = locationHistory.findLastLocation(routeInfo, delta);
incomingRouteParams = {
...prevRouteInfo,
routerAction: 'pop',
@ -191,7 +219,6 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
...incomingRouteParams,
lastPathname: leavingLocationInfo.pathname
}
locationHistory.add(routeInfo);
} else {
const isPushed = incomingRouteParams.routerAction === 'push' && incomingRouteParams.routerDirection === 'forward';
@ -215,7 +242,7 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
const lastRoute = locationHistory.getCurrentRouteInfoForTab(routeInfo.tab);
routeInfo.pushedByRoute = lastRoute?.pushedByRoute;
} else if (routeInfo.routerAction === 'replace') {
const currentRouteInfo = locationHistory.current();
const currentRouteInfo = locationHistory.last();
/**
* If going from /home to /child, then replacing from
@ -232,8 +259,27 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
routeInfo.prevRouteLastPathname = currentRouteInfo?.lastPathname;
}
}
routeInfo.position = currentHistoryPosition;
const historySize = locationHistory.size();
const historyDiff = currentHistoryPosition - initialHistoryPosition;
/**
* If the size of location history is greater
* than the difference between the current history
* position and the initial history position
* then we are guaranteed to already have a history
* item for this route. In other words, a user
* is navigating within the history without pushing
* new items within the stack.
*/
if (historySize > historyDiff && routeInfo.tab === undefined) {
locationHistory.updateByHistoryPosition(routeInfo);
} else {
locationHistory.add(routeInfo);
}
currentRouteInfo = routeInfo;
}
incomingRouteParams = undefined;
@ -301,7 +347,7 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
const handleSetCurrentTab = (tab: string) => {
currentTab = tab;
const ri = { ...locationHistory.current() };
const ri = { ...locationHistory.last() };
if (ri.tab !== tab) {
ri.tab = tab;
locationHistory.update(ri);
@ -313,7 +359,12 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
historyChangeListeners.push(cb);
}
const getLeavingRouteInfo = () => {
return locationHistory.current(initialHistoryPosition, currentHistoryPosition);
}
return {
getLeavingRouteInfo,
handleNavigateBack,
handleSetCurrentTab,
getCurrentRouteInfo,