From 2798254dab13f12be7a2291733bd24f10753f9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E6=B5=A9?= Date: Thu, 8 Aug 2024 15:13:35 +0800 Subject: [PATCH] feat: RouterStack --- .npmrc | 2 +- components.d.ts | 3 +- src/App.vue | 86 +------------------ src/components/TheWelcome.vue | 88 -------------------- src/components/WelcomeItem.vue | 87 ------------------- src/main.ts | 12 ++- src/pages/about-page.vue | 15 ---- src/pages/index-page.vue | 11 +-- src/pages/page-1.vue | 10 +++ src/pages/page-2.vue | 31 +++++++ src/pages/page-3.vue | 1 + src/router/guard/index.ts | 26 ++++++ src/router/guard/log-guard.ts | 147 +++++++++++++++++++++++++++++++++ src/router/index.ts | 23 ++---- src/types/router.ts | 21 +++++ src/types/shims.d.ts | 12 +++ tsconfig.app.json | 1 + typed-router.d.ts | 4 +- 18 files changed, 272 insertions(+), 308 deletions(-) delete mode 100644 src/components/TheWelcome.vue delete mode 100644 src/components/WelcomeItem.vue delete mode 100644 src/pages/about-page.vue create mode 100644 src/pages/page-1.vue create mode 100644 src/pages/page-2.vue create mode 100644 src/pages/page-3.vue create mode 100644 src/router/guard/index.ts create mode 100644 src/router/guard/log-guard.ts create mode 100644 src/types/router.ts create mode 100644 src/types/shims.d.ts diff --git a/.npmrc b/.npmrc index 960d73b..57ceda7 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,2 @@ use-node-version=20.16.0 -registry=https://registry.npmmirror.com +registry=https://npm-cf-proxy.oo1.dev diff --git a/components.d.ts b/components.d.ts index 1bc03a2..b567c37 100644 --- a/components.d.ts +++ b/components.d.ts @@ -15,7 +15,6 @@ declare module 'vue' { IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] - TheWelcome: typeof import('./src/components/TheWelcome.vue')['default'] - WelcomeItem: typeof import('./src/components/WelcomeItem.vue')['default'] + TButton: typeof import('tdesign-mobile-vue/esm')['Button'] } } diff --git a/src/App.vue b/src/App.vue index fa6c80b..613fac0 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,89 +1,5 @@ - + - - diff --git a/src/components/TheWelcome.vue b/src/components/TheWelcome.vue deleted file mode 100644 index 49d8f73..0000000 --- a/src/components/TheWelcome.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - diff --git a/src/components/WelcomeItem.vue b/src/components/WelcomeItem.vue deleted file mode 100644 index 6d7086a..0000000 --- a/src/components/WelcomeItem.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - diff --git a/src/main.ts b/src/main.ts index 50de07a..a073716 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,11 +5,9 @@ import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' -import router from './router' +import { router } from './router' -const app = createApp(App) - -app.use(createPinia()) -app.use(router) - -app.mount('#app') +createApp(App) + .use(createPinia()) + .use(router) + .mount('#app') diff --git a/src/pages/about-page.vue b/src/pages/about-page.vue deleted file mode 100644 index 756ad2a..0000000 --- a/src/pages/about-page.vue +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/src/pages/index-page.vue b/src/pages/index-page.vue index c980d55..f8d1683 100644 --- a/src/pages/index-page.vue +++ b/src/pages/index-page.vue @@ -1,12 +1,13 @@ diff --git a/src/pages/page-1.vue b/src/pages/page-1.vue new file mode 100644 index 0000000..036b984 --- /dev/null +++ b/src/pages/page-1.vue @@ -0,0 +1,10 @@ + diff --git a/src/pages/page-2.vue b/src/pages/page-2.vue new file mode 100644 index 0000000..f352e34 --- /dev/null +++ b/src/pages/page-2.vue @@ -0,0 +1,31 @@ + + + diff --git a/src/pages/page-3.vue b/src/pages/page-3.vue new file mode 100644 index 0000000..33afde8 --- /dev/null +++ b/src/pages/page-3.vue @@ -0,0 +1 @@ + diff --git a/src/router/guard/index.ts b/src/router/guard/index.ts new file mode 100644 index 0000000..7e338b9 --- /dev/null +++ b/src/router/guard/index.ts @@ -0,0 +1,26 @@ +import NProgress from 'nprogress' +import type { Router } from 'vue-router' +import { createLogGuard, createStackGuard } from './log-guard' + +// Don't change the order of creation +export function setupRouterGuard(router: Router) { + createProgressGuard(router) + + createLogGuard(router) + + createStackGuard(router) + + router.onError((error) => { + console.debug('๐Ÿšจ [router error]: ', error) + }) +} + +export function createProgressGuard(router: Router) { + router.beforeEach(() => { + NProgress.start() + }) + + router.afterEach(() => { + NProgress.done() + }) +} diff --git a/src/router/guard/log-guard.ts b/src/router/guard/log-guard.ts new file mode 100644 index 0000000..315d89a --- /dev/null +++ b/src/router/guard/log-guard.ts @@ -0,0 +1,147 @@ +import { START_LOCATION } from 'vue-router' +import type { RouteLocationNormalized, Router } from 'vue-router' + +export function createLogGuard(router: Router) { + router.beforeEach(async (to, from, next) => { + console.debug( + '๐Ÿš— ====================', + `[beforeEach]`, + `[${from === START_LOCATION ? 'START_LOCATION' : String(from.name || '')}]`, + `-> [${String(to.name)}].`, + '====================' + ) + next() + }) + + router.afterEach(async (to, from, failure) => { + console.debug( + '๐Ÿš— ====================', + ` [afterEach]`, + `[${from === START_LOCATION ? 'START_LOCATION' : String(from.name || '')}]`, + `-> [${String(to.name)}].`, + '==================== ๐Ÿš—๐Ÿš—๐Ÿš—', + `failure: `, + failure + ) + }) +} + + +export function createStackGuard(router: Router) { + // const stack = router.stack = { /* list: [] as RouteLocationNormalized[], */ currentStackIndex: 0 } + let startPosition = -1 + let curPosition = -1 + + // if ($__DEV__) Object.assign(window, { stack }) + + const _routerHistory = router.options.history + + /* window.addEventListener('beforeunload', function (event) { + console.debug("๐Ÿšฅ", '[onbeforeunload]', "event :>> ", event); + const confirmationMessage = "\\o/"; + + (event || window.event).returnValue = confirmationMessage; //Gecko + IE + return confirmationMessage; //Webkit, Safari, Chrome etc. + }) */ + + _routerHistory.listen((to, from, info) => { + console.debug('๐Ÿšฅ listen', ':') + console.debug('๐Ÿšฅ listen', 'from :>> ', from) + console.debug('๐Ÿšฅ listen', 'to :>> ', to) // TODO: ๅœจafterEach้‚ฃ้‡Œๆ ธๅฏน + console.debug('๐Ÿšฅ listen', 'info :>> ', info) + // lastNavigationInfo.lastInfo = info; + }); + + // ############################# + // ้‡ๅ†™ router.history ๆ–นๆณ• + // ############################# + (() => { + const routerHistoryPush = _routerHistory.push + _routerHistory.push = function (...args) { + console.debug('๐Ÿšฅ [router]', 'push: args :>> ', args) + return routerHistoryPush.call(this, ...args) + } + + const routerHistoryReplace = _routerHistory.replace + _routerHistory.replace = function (...args) { + console.debug('๐Ÿšฅ [router]', 'replace: args :>> ', args) + // lastNavigationInfo.replace = true; + return routerHistoryReplace.call(this, ...args) + } + + const routerHistoryGo = _routerHistory.go + _routerHistory.go = function (...args) { + console.debug('๐Ÿšฅ [router]', 'go: args :>> ', args) + return routerHistoryGo.call(this, ...args) + } + })/* () */; + + // ############################# + // ้‡ๅ†™ window.history ๆ–นๆณ• + // ############################# + (() => { + const browserHistoryBack = window.history.back + window.history.back = function (...args) { + console.debug('๐ŸŒ [Browser]', 'history.back: args :>> ', args) + return browserHistoryBack.call(this, ...args) + } + + const browserHistoryForward = window.history.forward + window.history.forward = function (...args) { + console.debug('๐ŸŒ [Browser]', 'history.forward: args :>> ', args) + return browserHistoryForward.call(this, ...args) + } + + const browserHistoryGo = window.history.go + window.history.go = function (...args) { + console.debug('๐ŸŒ [Browser]', 'history.go: args :>> ', args) + return browserHistoryGo.call(this, ...args) + } + + const browserHistoryPushState = window.history.pushState + window.history.pushState = function (...args) { + console.debug('๐ŸŒ [Browser]', 'history.pushState: args :>> ', args) + return browserHistoryPushState.call(this, ...args) + } + + const browserHistoryReplaceState = window.history.replaceState + window.history.replaceState = function (...args) { + console.debug('๐ŸŒ [Browser]', 'history.replaceState: args :>> ', args) + return browserHistoryReplaceState.call(this, ...args) + } + })/* () */; + + router.beforeEach(async (to) => { + if (to.name === 'Page3') { + return { name: 'Page2' } + } + }) + + router.afterEach(async (to, from, failure) => { + if (failure) return + + if (from === START_LOCATION) { + startPosition = history.state.position + curPosition = startPosition - 1 + } + + const newPostion = history.state.position + // console.log('history.state.position :>> ', history.state.position); + console.log('startPosition :>> ', startPosition); + console.log('newPostion :>> ', newPostion); + + const delta = newPostion - curPosition + if (newPostion > curPosition) { + console.log('๐Ÿ‘‰๐Ÿป'); + } else if (newPostion < curPosition) { + console.log('๐Ÿ‘ˆ๐Ÿป'); + } else { + console.log('๐Ÿ‘Œ๐Ÿป'); + } + console.log('delta :>> ', delta); + + curPosition = newPostion; + + console.log(`%c${'-'.repeat(80)}`, 'color: #409EFF;') + }) +} diff --git a/src/router/index.ts b/src/router/index.ts index 385f803..1e7f7cc 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,27 +1,16 @@ import { createRouter, createWebHistory } from 'vue-router' import { routes, handleHotUpdate } from 'vue-router/auto-routes' +import { setupRouterGuard } from './guard' export const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), - // routes: [ - // { - // path: '/', - // name: 'home', - // component: HomeView - // }, - // { - // path: '/about', - // name: 'about', - // // route level code-splitting - // // this generates a separate chunk (About.[hash].js) for this route - // // which is lazy-loaded when the route is visited. - // component: () => import('../views/AboutView.vue') - // } - // ], - routes + routes, + strict: true }) -export default router +if ($__DEV__) Object.assign(window, { router }) + +setupRouterGuard(router) if (import.meta.hot) { handleHotUpdate(router) diff --git a/src/types/router.ts b/src/types/router.ts new file mode 100644 index 0000000..f7daef8 --- /dev/null +++ b/src/types/router.ts @@ -0,0 +1,21 @@ +import 'vue-router' + +// ไธบไบ†็กฎไฟ่ฟ™ไธชๆ–‡ไปถ่ขซๅฝ“ไฝœไธ€ไธชๆจกๅ—๏ผŒๆทปๅŠ ่‡ณๅฐ‘ไธ€ไธช `export` ๅฃฐๆ˜Ž +export { } + +// declare module 'vue-router' { +// interface RouteMeta { +// // fromList?: RouteLocationNormalized[] +// } + +// interface Router { +// stack: { +// // list: RouteLocationNormalizedLoaded[] +// // currentStackIndex: number +// } +// } +// interface RouteLocationNormalizedGeneric { +// // from: RouteLocationNormalizedLoaded +// // stackIndex: number +// } +// } diff --git a/src/types/shims.d.ts b/src/types/shims.d.ts new file mode 100644 index 0000000..30f043c --- /dev/null +++ b/src/types/shims.d.ts @@ -0,0 +1,12 @@ +export {} + +declare global { + const $__DEV__: boolean +} + +/* declare module 'vue' { + export interface ComponentCustomProperties { + $__DEV__: boolean; + } +} + */ diff --git a/tsconfig.app.json b/tsconfig.app.json index 9a2fbc2..3c58f54 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -15,6 +15,7 @@ ], "compilerOptions": { "composite": true, + // "skipLibCheck": false, "moduleResolution": "Bundler", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "baseUrl": ".", diff --git a/typed-router.d.ts b/typed-router.d.ts index ba19764..96308fc 100644 --- a/typed-router.d.ts +++ b/typed-router.d.ts @@ -18,7 +18,9 @@ declare module 'vue-router/auto-routes' { * Route name map generated by unplugin-vue-router */ export interface RouteNamedMap { - 'AboutPage': RouteRecordInfo<'AboutPage', '/about-page', Record, Record>, 'IndexPage': RouteRecordInfo<'IndexPage', '/index-page', Record, Record>, + 'Page1': RouteRecordInfo<'Page1', '/page-1', Record, Record>, + 'Page2': RouteRecordInfo<'Page2', '/page-2', Record, Record>, + 'Page3': RouteRecordInfo<'Page3', '/page-3', Record, Record>, } }