1+ import { $t } from '@/i18n' ;
2+ import { useDialog } from 'naive-ui' ;
13import { computed , ref , type Ref } from 'vue' ;
4+ import { onBeforeRouteLeave } from 'vue-router' ;
25
36export function useModelChanges ( model : Ref < Record < string , unknown > | undefined > ) {
7+ const dialog = useDialog ( ) ;
48 const valuesToJSON = ( o : Record < string , unknown > | undefined ) =>
59 Object . fromEntries ( Object . entries ( o || { } ) . map ( ( [ k , v ] ) => [ k , JSON . stringify ( v ) ] ) ) ;
610 const beforeEntriesJson = ref ( valuesToJSON ( model . value ) ) ;
@@ -9,6 +13,25 @@ export function useModelChanges(model: Ref<Record<string, unknown> | undefined>)
913 Object . entries ( afterEntriesJson . value ) . some ( ( [ k , v ] ) => v !== beforeEntriesJson . value [ k ] )
1014 ) ;
1115
16+ // register router guard to prevent navigation if there are unsaved changes
17+ onBeforeRouteLeave (
18+ async ( _to , _from ) =>
19+ ! changed . value ||
20+ ( await new Promise ( ( resolve ) =>
21+ dialog . warning ( {
22+ title : $t ( 'common.warning' ) ,
23+ content : $t ( 'common.dirtyFormConfirm' ) ,
24+ positiveText : $t ( 'common.yes' ) ,
25+ negativeText : $t ( 'common.no' ) ,
26+ onPositiveClick : ( ) => resolve ( true ) ,
27+ onNegativeClick : ( ) => resolve ( false ) ,
28+ onClose : ( ) => resolve ( false ) ,
29+ onEsc : ( ) => resolve ( false ) ,
30+ onMaskClick : ( ) => resolve ( false ) ,
31+ } )
32+ ) )
33+ ) ;
34+
1235 function getChanges ( forceProps ?: string [ ] ) {
1336 if ( ! changed . value ) {
1437 return { } ;
0 commit comments