Nuxt/packages/nuxt3/src/app/composables/router.ts

82 lines
2.5 KiB
TypeScript
Raw Normal View History

import type { Router, RouteLocationNormalizedLoaded, NavigationGuard, RouteLocationNormalized, RouteLocationRaw, NavigationFailure } from 'vue-router'
import { sendRedirect } from 'h3'
import { useNuxtApp } from '#app'
export const useRouter = () => {
return useNuxtApp()?.$router as Router
}
export const useRoute = () => {
return useNuxtApp()._route as RouteLocationNormalizedLoaded
}
export const useActiveRoute = () => {
return useNuxtApp()._activeRoute as RouteLocationNormalizedLoaded
}
export interface RouteMiddleware {
(to: RouteLocationNormalized, from: RouteLocationNormalized): ReturnType<NavigationGuard>
}
export const defineNuxtRouteMiddleware = (middleware: RouteMiddleware) => middleware
export interface AddRouteMiddlewareOptions {
global?: boolean
}
interface AddRouteMiddleware {
(name: string, middleware: RouteMiddleware, options?: AddRouteMiddlewareOptions): void
(middleware: RouteMiddleware): void
}
export const addRouteMiddleware: AddRouteMiddleware = (name: string | RouteMiddleware, middleware?: RouteMiddleware, options: AddRouteMiddlewareOptions = {}) => {
const nuxtApp = useNuxtApp()
if (options.global || typeof name === 'function') {
nuxtApp._middleware.global.push(typeof name === 'function' ? name : middleware)
} else {
nuxtApp._middleware.named[name] = middleware
}
}
const isProcessingMiddleware = () => {
try {
if (useNuxtApp()._processingMiddleware) {
return true
}
} catch {
// Within an async middleware
return true
}
return false
}
export interface NavigateToOptions {
replace?: boolean
}
export const navigateTo = (to: RouteLocationRaw, options: NavigateToOptions = {}): Promise<void | NavigationFailure> | RouteLocationRaw => {
if (isProcessingMiddleware()) {
return to
}
const router = useRouter()
if (process.server && useNuxtApp().ssrContext) {
// Server-side redirection using h3 res from ssrContext
const res = useNuxtApp().ssrContext?.res
const redirectLocation = router.resolve(to).fullPath
return sendRedirect(res, redirectLocation)
}
// Client-side redirection using vue-router
return options.replace ? router.replace(to) : router.push(to)
}
/** This will abort navigation within a Nuxt route middleware handler. */
export const abortNavigation = (err?: Error | string) => {
if (process.dev && !isProcessingMiddleware()) {
throw new Error('abortNavigation() is only usable inside a route middleware handler.')
}
if (err) {
throw err instanceof Error ? err : new Error(err)
}
return false
}