|
// This is a gist to describe the concept and not a full working example. |
|
|
|
// Use this hook to signal to the app that you would like to block navigation when your form is dirty |
|
|
|
useNavigationGuard(form.isDirty, { |
|
message: "Your work hasn't been saved. Are you sure you want to continue?", |
|
cancel: 'Go Back', |
|
proceed: 'Continue without saving' |
|
}) |
|
|
|
// Rough implementation below |
|
|
|
interface NavigationGuardOptions { |
|
message: string; |
|
cancelLabel: string; |
|
proceedLabel: string; |
|
} |
|
|
|
const useNavigationGuard = (isBlocked: MaybeRef<boolean>, options) => { |
|
|
|
// Navigation Guard is |
|
const guard: NavigationGuard = (from, to) => { |
|
|
|
if(!isBlocked.value) { |
|
// This guard is not blocking, continue navigation |
|
return true; |
|
} |
|
|
|
// Otherwise, lets ask the user (async!) |
|
// ..and showConfirm should likely be injected so that the app can decide how to show the confirmation dialog |
|
// Do you want it to be a browser dialog or some other dom element system? |
|
const result = await showConfirm(options); |
|
|
|
return result; |
|
}) |
|
|
|
// NavigationManager is a special singleton service that manages a list of form guards that must be consulted before |
|
// allowing navigation. |
|
// This should get hooked in to the SPA router's guard system, but there is also an opportunity to |
|
// hook into any large tab navigation systems you have. |
|
onComponentMounted(() => { |
|
NavigationManager.addGuard(guard) |
|
}) |
|
|
|
onComponentWillUnmount(() => { |
|
NavigationManager.removeGuard(guard) |
|
}) |
|
|
|
// and also handle the window.unload case |
|
useWindowUnload(...); |
|
|
|
|
|
} |
|
|
|
const useWindowUnload = (isBlocked: MaybeRef<boolean>, message: string) => { |
|
|
|
useEventListener(window, 'beforeunload', (e) => { |
|
// https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#examples |
|
const _isBlocked = unref(isBlocked); |
|
|
|
if (_isBlocked) { |
|
e.preventDefault(); |
|
e.returnValue = message; |
|
|
|
return e.returnValue; |
|
} |
|
}); |
|
|
|
} |