mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-17 18:54:11 +08:00
fix(vue): using router.go now shows correct view (#23773)
resolves #22563
This commit is contained in:
@ -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,
|
||||
|
Reference in New Issue
Block a user