Я использую Vuejs с Vuetify и Vuex и хочу создать простое приложение. Скажем, очень маленькое приложение todo. Для моего бэкэнда я использую Express REST API, а для методов HTTP я использую Axios.
Чтобы справиться с сеансом, я прочитал о двух вещах:
При запуске вызова Axios я мог получить ошибку с кодом состояния 401
. Я мог бы справиться с этим, используя axios.interceptors.response
.
instance.interceptors.response.use(res => res, (err) => {
if (err.response.status === 401) {
store.dispatch('authentication/destroySession');
}
return err;
});
При перенаправлении на другой маршрут я мог бы использовать событие beforeRouteEnter
Vue Router
и проверить, действителен ли токен и не истек ли срок его действия.
router.beforeEach((to, from, next) => {
const userIsLoggedIn = checkIfUserIsLoggedIn();
if (!userIsLoggedIn) {
next(false); // stay on this route
} else {
next(); // navigate to the next route
}
});
Все идет нормально. Но что произойдет, если один из этих подходов будет иметь дело с состоянием «не вошел в систему»? Я не хочу перенаправлять пользователя на страницу входа, потому что тогда он потеряет свою текущую работу. И, возможно, у него нет учетной записи, поэтому ему нужно сначала зарегистрироваться.
Если маршрут или конечная точка REST защищены, я бы отменил задачу для выполнения, покажу предупреждение об ошибке, а после этого я хотел бы отобразить наложение.
Большинство ресурсов объясняют, как перенаправить на страницу входа, если вы не вошли в систему, но Github, например, отображает страницу входа и выполняет задачу после входа в систему.
Как я могу визуализировать это наложение? Это вообще возможно? Есть ли лучший подход?
@Dan да, но мой единственный вопрос, как я могу отобразить наложение, не удаляя текущий вид :) Это произойдет в моем App.vue
, но я не знаю, как настроить такое наложение
Я разместил ответ, чтобы показать вам
Создайте оверлейный HTML-код (может быть в App.vue
, как вы упомянули), видимость которого зависит от вычисляемого имени showOverlay
:
<div v-show = "showOverlay">OVERLAY CONTENT</div>
В вашем хранилище Vuex поддерживайте некоторое состояние, которое представляет видимость наложения:
state.showOverlay = false;
Вернувшись в App.vue
, сопоставьте это состояние Vuex с вычисленным showOverlay
:
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['showOverlay'])
}
}
Везде, где вы используете beforeRouteEnter
, или в маршрутизаторе, если используете beforeEach
, импортируйте хранилище Vuex напрямую (это упрощает доступ к хранилищу, когда this.$store
недоступен):
import store from '@/store.js';
Я вижу, вы разместили пример кода, который использует beforeEach
вместо beforeRouteEnter
, поэтому используйте что-то вроде:
router.beforeEach((to, from, next) => {
const userIsLoggedIn = checkIfUserIsLoggedIn();
if (!userIsLoggedIn) {
store.state.showOverlay = true;
next(false); // stay on this route
} else {
next(); // navigate to the next route
}
});
После того, как вы заработаете, было бы лучше переместить наложение в компонент, чтобы избежать ненужного редактирования App.vue
. И вам нужно будет вернуть оверлею состояние false
при закрытии.
Это, кажется, использует другой, действительный подход. Отображение компонента входа, если пользователь не вошел в систему. Но вы упомянули, что не хотите перенаправлять на подобную страницу, и спросили, как вместо этого использовать оверлей :)
спасибо, но я думаю, что не понял вашего первого пункта. В чем разница? Как бы вы тогда управляли этим наложением? Без использования оператора if? Я думаю, что не понял вашего решения, потому что думаю, что мой подход будет вашим...
Разница: в своем первоначальном вопросе вы представили, что пользователь выполняет работу на незащищенном маршруте, а затем пытается выполнить какое-либо действие, требующее входа в систему. В вашем втором примере корень приложения ничего не показывает, если пользователь не вошел в систему, поэтому работа, которую вы предполагали, была бы невозможна в первую очередь. В вашем исходном вопросе даже не нужно beforeRouteEnter
, потому что вы можете просто показать оверлей, когда пользователь нажимает Save
, или любое другое действие, требующее входа в систему. Я думаю, что вы перепутали несколько шаблонов проектирования.
Основываясь на наших комментариях, я думаю, что вы действительно хотите показать оверлей входа до, который вы отправляете запрос Axios, если пользователь не вошел в систему.
В beforeRouteEnter вы можете вызвать
next(false)
, чтобы прервать навигацию, а затем установить некоторое состояние для реактивного запуска отображения наложения.