#vue.js #vue-router
Вопрос:
У меня есть приложение Vue со многими дочерними компонентами. В моем случае у меня есть некоторые родительско-дочерние компоненты, подобные этому. Проблема в том, что в некоторых дочерних компонентах у меня есть раздел для редактирования информации. В случае, если пользователь ввел некоторую информацию и перешел на другую страницу, но не сохранил ее, будет отображен режим, предупреждающий пользователя. Я следовал инструкциям на beforeRouteLeave, и это сработало хорошо, но у меня возникла проблема. Когда я нажму кнопку » Да » в модальном режиме, я выдам функцию @yes='confirm'
родительскому компоненту. В функции подтверждения я установлю this.isConfirm = true
. Затем я проверяю эту переменную внутри перед выходом, чтобы подтвердить навигацию. Но на самом деле, когда я нажимаю кнопку » Да » в модальном режиме, экран не перенаправляется сразу. Мне нужно нажать еще раз, чтобы перенаправить. Помогите мне с этим делом
Ответ №1:
Вы можете создать базовый компонент, подобный следующему, а затем унаследовать (расширить) от него все компоненты уровня страницы/маршрута, в которых вы хотите реализовать функциональность (предупреждение о несохраненных данных).:
<template>
<div />
</template>
<script>
import events, { PAGE_LEAVE } from '@/events';
export default
{
name: 'BasePageLeave',
beforeRouteLeave(to, from, next)
{
events.$emit(PAGE_LEAVE, to, from, next);
}
};
</script>
events.js
это просто глобальный автобус событий.
Затем в своем компоненте на уровне страницы вы сделаете что-то вроде этого:
<template>
<div>
.... your template ....
<!-- Unsaved changes -->
<ConfirmPageLeave :value="modified" />
</div>
</template>
<script>
import BasePage from 'src/components/BasePageLeave';
import ConfirmPageLeave from 'src/components/dialogs/ConfirmPageLeave';
export default
{
name: 'MyRouteName',
components:
{
ConfirmPageLeave,
},
extends: BasePage,
data()
{
return {
modified: false,
myData:
{
... the data that you want to track and show a warning
}
};
}.
watch:
{
myData:
{
deep: true,
handler()
{
this.modified = true;
}
}
},
ConfirmPageLeave
Компонент представляет собой модальное диалоговое окно, которое будет отображаться, когда данные будут изменены И пользователь попытается уйти:
<template>
<v-dialog v-model="showUnsavedWarning" persistent>
<v-card flat>
<v-card-title class="pa-2">
<v-spacer />
<v-btn icon @click="showUnsavedWarning = false">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text class="pt-2 pb-3 text-h6">
<div class="text-h4 pb-4">{{ $t('confirm_page_leave') }}</div>
<div>{{ $t('unsaved_changes') }}</div>
</v-card-text>
<v-card-actions class="justify-center px-3 pb-3">
<v-btn class="mr-4 px-4" outlined large tile @click="showUnsavedWarning = false">{{ $t('go_back') }}</v-btn>
<v-btn class="ml-4 px-4" large tile depressed color="error" @click="ignoreUnsaved">{{ $t('ignore_changes') }}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
import events, { PAGE_LEAVE } from '@/events';
export default
{
name: 'ConfirmPageLeave',
props:
{
value:
{
// whether the monitored data has been modified
type: Boolean,
default: false
}
},
data()
{
return {
showUnsavedWarning: false,
nextRoute: null,
};
},
watch:
{
showUnsavedWarning(newVal)
{
if (!newVal)
{
this.nextRoute = null;
}
},
},
created()
{
events.$on(PAGE_LEAVE, this.discard);
window.addEventListener('beforeunload', this.pageLeave);
},
beforeDestroy()
{
events.$off(PAGE_LEAVE, this.discard);
window.removeEventListener('beforeunload', this.pageLeave);
},
methods:
{
discard(to, from, next)
{
if (this.value)
{
this.nextRoute = next;
this.showUnsavedWarning = true;
}
else next();
},
pageLeave(e)
{
if (this.value)
{
const confirmationMsg = this.$t('leave_page');
(e || window.event).returnValue = confirmationMsg;
return confirmationMsg;
}
},
ignoreUnsaved()
{
this.showUnsavedWarning = false;
if (this.nextRoute) this.nextRoute();
},
}
};
</script>
<i18n>
{
"en": {
"confirm_page_leave": "Unsaved changes",
"unsaved_changes": "If you leave this page, any unsaved changes will be lost.",
"ignore_changes": "Leave page",
"go_back": "Cancel",
"leave_page": "You're leaving the page but there are unsaved changes.nPress OK to ignore changes and leave the page or CANCEL to stay on the page."
}
}
</i18n>