前言
由於 Nuxt 接管了瀏覽器路由,所以除了使用瀏覽器內建的確認視窗,還需要搭配 Nuxt 的 onBeforeRouteLeave
、onBeforeRouteUpdate
以及瀏覽器內建的 window.confirm
來實作確認視窗。
實作
在 composables
資料夾,新增 useFormConfirmation.js
檔。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| const handleBeforeUnload = (e) => { e.preventDefault(); e.returnValue = true; };
const confirm = (next, text) => { const ok = window.confirm(text); if (ok) { window.removeEventListener('beforeunload', handleBeforeUnload); next(); return; } next(false); };
export default function () { const enabled = ref(false); const message = ref('');
onMounted(() => { window.addEventListener('beforeunload', handleBeforeUnload); });
onBeforeRouteLeave((to, from, next) => { if (enabled.value) { confirm(next, message.value); return; } next(); });
onBeforeRouteUpdate((to, from, next) => { if (enabled.value) { confirm(next, message.value); return; } next(); });
const setEnabled = (v) => { enabled.value = v; }; const setMessage = (v) => { message.value = v; };
return { setEnabled, setMessage, }; }
|
在 components
資料夾,新增 AppFormConfirmation.vue
檔。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <script setup> const { t } = useI18n(); const { setMessage, setEnabled } = useFormConfirmation();
const props = defineProps({ formData: { type: Object, default: null, }, });
setMessage(t('__instructionLeaveSite'));
const state = reactive({ formData: {}, });
if (props.formData) { state.formData = props.formData; }
const unwatch = watch(state.formData, () => { setEnabled(true); unwatch(); }); </script>
<template> <div /> </template>
|
在元間中使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <script setup> const state = reactive({ formData: { } }); </script>
<template> <div> <AppFormConfirmation :form-data="state.formData" /> <v-form> </v-form> </div> </template>
|
參考資料