mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
feat(nuxt): add onBeforeRouteLeave
and onBeforeRouteUpdate
composables (#8889)
This commit is contained in:
parent
3e34a61506
commit
e6351349c0
@ -10,7 +10,7 @@ export type { FetchResult, UseFetchOptions } from './fetch'
|
||||
export { useCookie } from './cookie'
|
||||
export type { CookieOptions, CookieRef } from './cookie'
|
||||
export { useRequestHeaders, useRequestEvent, setResponseStatus } from './ssr'
|
||||
export { abortNavigation, addRouteMiddleware, defineNuxtRouteMiddleware, setPageLayout, navigateTo, useRoute, useActiveRoute, useRouter } from './router'
|
||||
export { abortNavigation, addRouteMiddleware, defineNuxtRouteMiddleware, onBeforeRouteLeave, onBeforeRouteUpdate, setPageLayout, navigateTo, useRoute, useActiveRoute, useRouter } from './router'
|
||||
export type { AddRouteMiddlewareOptions, RouteMiddleware } from './router'
|
||||
export { preloadComponents, prefetchComponents, preloadRouteComponents } from './preload'
|
||||
export { isPrerendered, loadPayload, preloadPayload } from './payload'
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getCurrentInstance, inject } from 'vue'
|
||||
import { getCurrentInstance, inject, onUnmounted } from 'vue'
|
||||
import type { Router, RouteLocationNormalizedLoaded, NavigationGuard, RouteLocationNormalized, RouteLocationRaw, NavigationFailure, RouteLocationPathRaw } from 'vue-router'
|
||||
import { sendRedirect } from 'h3'
|
||||
import { hasProtocol, joinURL, parseURL } from 'ufo'
|
||||
@ -17,6 +17,19 @@ export const useRoute = (): RouteLocationNormalizedLoaded => {
|
||||
return useNuxtApp()._route
|
||||
}
|
||||
|
||||
export const onBeforeRouteLeave = (guard: NavigationGuard) => {
|
||||
const unsubscribe = useRouter().beforeEach((to, from, next) => {
|
||||
if (to === from) { return }
|
||||
return guard(to, from, next)
|
||||
})
|
||||
onUnmounted(unsubscribe)
|
||||
}
|
||||
|
||||
export const onBeforeRouteUpdate = (guard: NavigationGuard) => {
|
||||
const unsubscribe = useRouter().beforeEach(guard)
|
||||
onUnmounted(unsubscribe)
|
||||
}
|
||||
|
||||
/** @deprecated Use `useRoute` instead. */
|
||||
export const useActiveRoute = (): RouteLocationNormalizedLoaded => {
|
||||
return useNuxtApp()._route
|
||||
|
@ -31,23 +31,26 @@ export default defineNuxtModule<Partial<ImportsOptions>>({
|
||||
options = defu(nuxt.options.autoImports, options)
|
||||
}
|
||||
|
||||
// Allow modules extending sources
|
||||
await nuxt.callHook('imports:sources', options.presets as ImportPresetWithDeprecation[])
|
||||
// TODO: fix sharing of defaults between invocations of modules
|
||||
const presets = JSON.parse(JSON.stringify(options.presets)) as ImportPresetWithDeprecation[]
|
||||
|
||||
options.presets?.forEach((_i) => {
|
||||
// Allow modules extending sources
|
||||
await nuxt.callHook('imports:sources', presets)
|
||||
|
||||
for (const _i of presets) {
|
||||
const i = _i as ImportPresetWithDeprecation | string
|
||||
if (typeof i !== 'string' && i.names && !i.imports) {
|
||||
i.imports = i.names
|
||||
logger.warn('imports: presets.names is deprecated, use presets.imports instead')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Filter disabled sources
|
||||
// options.sources = options.sources.filter(source => source.disabled !== true)
|
||||
|
||||
// Create a context to share state between module internals
|
||||
const ctx = createUnimport({
|
||||
presets: options.presets,
|
||||
presets,
|
||||
imports: options.imports,
|
||||
virtualImports: ['#imports'],
|
||||
addons: {
|
||||
|
@ -64,6 +64,15 @@ const appPreset = defineUnimportPreset({
|
||||
]
|
||||
})
|
||||
|
||||
// vue-router
|
||||
const routerPreset = defineUnimportPreset({
|
||||
from: '#app',
|
||||
imports: [
|
||||
'onBeforeRouteLeave',
|
||||
'onBeforeRouteUpdate'
|
||||
]
|
||||
})
|
||||
|
||||
// vue
|
||||
const vuePreset = defineUnimportPreset({
|
||||
from: 'vue',
|
||||
@ -140,5 +149,6 @@ const vuePreset = defineUnimportPreset({
|
||||
export const defaultPresets: InlinePreset[] = [
|
||||
...commonPresets,
|
||||
appPreset,
|
||||
routerPreset,
|
||||
vuePreset
|
||||
]
|
||||
|
@ -54,6 +54,14 @@ export default defineNuxtModule({
|
||||
references.push({ types: 'vue-router' })
|
||||
})
|
||||
|
||||
// Add vue-router route guard imports
|
||||
nuxt.hook('imports:sources', (sources) => {
|
||||
const routerImports = sources.find(s => s.from === '#app' && s.imports.includes('onBeforeRouteLeave'))
|
||||
if (routerImports) {
|
||||
routerImports.from = 'vue-router'
|
||||
}
|
||||
})
|
||||
|
||||
// Regenerate templates when adding or removing pages
|
||||
nuxt.hook('builder:watch', async (event, path) => {
|
||||
const dirs = [
|
||||
|
@ -66,7 +66,7 @@ describe('imports:nuxt', () => {
|
||||
continue
|
||||
}
|
||||
it(`should register ${name} globally`, () => {
|
||||
expect(defaultPresets.find(a => a.from === '#app')!.imports).to.include(name)
|
||||
expect(defaultPresets.flatMap(a => a.from === '#app' ? a.imports : [])).to.include(name)
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
|
Loading…
Reference in New Issue
Block a user