From fef3644067b7ccac96ec9ae122e3f1c8b8fc58ef Mon Sep 17 00:00:00 2001 From: vben Date: Fri, 4 Dec 2020 21:52:29 +0800 Subject: [PATCH] fix: page switching did not return to the top --- src/router/guard/index.ts | 13 ++++++++- src/router/index.ts | 4 ++- src/router/scrollBehaviour.ts | 55 +++++++++++++++++------------------ 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/router/guard/index.ts b/src/router/guard/index.ts index 66019473..9c0a401a 100644 --- a/src/router/guard/index.ts +++ b/src/router/guard/index.ts @@ -1,4 +1,4 @@ -import { isNavigationFailure, Router } from 'vue-router'; +import { isNavigationFailure, RouteLocationNormalized, Router } from 'vue-router'; import { Modal, notification } from 'ant-design-vue'; @@ -19,6 +19,12 @@ import { REDIRECT_NAME } from '/@/router/constant'; const { closeMessageOnSwitch, removeAllHttpPending } = useProjectSetting(); const globSetting = useGlobSetting(); +const body = document.body; + +const isHash = (href: string) => { + return /^#/.test(href); +}; + export function createGuard(router: Router) { let axiosCanceler: Nullable; if (removeAllHttpPending) { @@ -45,8 +51,13 @@ export function createGuard(router: Router) { }); router.afterEach((to, from, failure) => { + // scroll top + isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0); + loadedPageMap.set(to.path, true); + const { t } = useI18n(); + // change html title to.name !== REDIRECT_NAME && setTitle(t(to.meta.title), globSetting.title); diff --git a/src/router/index.ts b/src/router/index.ts index ad2218ae..3c5d4aab 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -8,9 +8,11 @@ import { createGuard } from './guard/'; import { basicRoutes } from './routes/'; import { scrollBehavior } from './scrollBehaviour'; +export const hashRouter = createWebHashHistory(); + // app router const router = createRouter({ - history: createWebHashHistory(), + history: hashRouter, routes: basicRoutes as RouteRecordRaw[], strict: true, scrollBehavior: scrollBehavior, diff --git a/src/router/scrollBehaviour.ts b/src/router/scrollBehaviour.ts index 2b0d03ad..d9a7ee8e 100644 --- a/src/router/scrollBehaviour.ts +++ b/src/router/scrollBehaviour.ts @@ -1,3 +1,27 @@ +// see https://github.com/vuejs/vue-router-next/blob/master/playground/scrollWaiter.ts +import type { RouteLocationNormalized } from 'vue-router'; +// class ScrollQueue { +// private resolve: (() => void) | null = null; +// private promise: Promise | null = null; + +// add() { +// this.promise = new Promise((resolve) => { +// this.resolve = resolve as () => void; +// }); +// } + +// flush() { +// this.resolve && this.resolve(); +// this.resolve = null; +// this.promise = null; +// } + +// async wait() { +// await this.promise; +// } +// } +// const scrollWaiter = new ScrollQueue(); + /** * Handles the scroll behavior on route navigation * @@ -8,10 +32,9 @@ */ // @ts-ignore export async function scrollBehavior(to, from, savedPosition) { - await scrollWaiter.wait(); + // await scrollWaiter.wait(); // Use predefined scroll behavior if defined, defaults to no scroll behavior - const behavior = document.documentElement.style.scrollBehavior || 'auto'; - + const behavior = 'smooth'; // Returning the `savedPosition` (if available) will result in a native-like // behavior when navigating with back/forward buttons if (savedPosition) { @@ -24,7 +47,7 @@ export async function scrollBehavior(to, from, savedPosition) { } // Check if any matched route config has meta that discourages scrolling to top - if (to.matched.some((m: any) => m.meta.scrollToTop === false)) { + if (to.matched.some((m: RouteLocationNormalized) => m.meta.scrollToTop === false)) { // Leave scroll as it is return false; } @@ -32,27 +55,3 @@ export async function scrollBehavior(to, from, savedPosition) { // Always scroll to top return { left: 0, top: 0, behavior }; } - -// see https://github.com/vuejs/vue-router-next/blob/master/playground/scrollWaiter.ts -class ScrollQueue { - private resolve: (() => void) | null = null; - private promise: Promise | null = null; - - add() { - this.promise = new Promise((resolve) => { - this.resolve = resolve as () => void; - }); - } - - flush() { - this.resolve && this.resolve(); - this.resolve = null; - this.promise = null; - } - - async wait() { - await this.promise; - } -} - -export const scrollWaiter = new ScrollQueue(); -- GitLab