60 lines
1.4 KiB
TypeScript
60 lines
1.4 KiB
TypeScript
/**
|
||
* router/index.ts
|
||
*
|
||
* Manual routes for ./src/pages/*.vue
|
||
*/
|
||
|
||
// Composables
|
||
import { createRouter, createWebHistory } from 'vue-router'
|
||
import { HTTP_ERROR_EVENT, type HttpErrorDetail } from '@/services/http-error'
|
||
import { registerGuards } from './guards'
|
||
import { routes } from './routes'
|
||
|
||
const router = createRouter({
|
||
history: createWebHistory(import.meta.env.BASE_URL),
|
||
routes,
|
||
scrollBehavior(to, _from, savedPosition) {
|
||
// Back/Forward 恢復滾動位置(Restore scroll position)
|
||
if (savedPosition) return savedPosition
|
||
// hash anchor
|
||
if (to.hash) return { el: to.hash, behavior: 'smooth' }
|
||
return { top: 0 }
|
||
},
|
||
})
|
||
|
||
registerGuards(router)
|
||
|
||
function getErrorRouteName(status?: number) {
|
||
switch (status) {
|
||
case 403: {
|
||
return 'forbidden'
|
||
}
|
||
case 404: {
|
||
return 'not-found'
|
||
}
|
||
case 500: {
|
||
return 'server-error'
|
||
}
|
||
case 503: {
|
||
return 'maintenance'
|
||
}
|
||
default: {
|
||
return 'network-error'
|
||
}
|
||
}
|
||
}
|
||
|
||
window.addEventListener(HTTP_ERROR_EVENT, (event: Event) => {
|
||
const detail = (event as CustomEvent<HttpErrorDetail>).detail
|
||
const name = getErrorRouteName(detail?.status)
|
||
if (router.currentRoute.value.name === name) return
|
||
|
||
const message = detail?.message?.trim()
|
||
void router.replace({
|
||
name,
|
||
query: message ? { message } : undefined,
|
||
})
|
||
})
|
||
|
||
export default router
|