@AnastasiyaLebedevich
Начинающий frontend developer

Как правильно выполнить динамический vue роутинг?

Хочу сделать динамический роутинг для сайта, который зависит от изменения agreement. Есть следующее дерево путей:

const routes = [
    {
        path: "/",
        redirect: "/home",
        component: DefaultLayout,
        meta: {
            requiresAuth: true,
        },
        children: [
            {
                path: "/home",
                name: "HomeView",
                component: HomeView,
            },
            {
                path: "/calendar",
                name: "CalendarView",
                component: CalendarView,
            },
            {
                path: "/notes",
                name: "NotesView",
                component: NotesView,
            },
            {
                path: "/settings",
                name: "SettingsView",
                component: SettingsView,
            },
        ],
    },
    {
        path: "/terms-of-use",
        name: "TermsOfUseView",
        component: TermsOfUseView,
        meta: {
            isGuest: true,
        },
    },
    {
        path: "/agreement",
        redirect: "/offer",
        component: AgreementLayout,
        children: [
            {
                path: "/offer",
                name: "OfferView",
                component: OfferView,
            },
            {
                path: "/public",
                name: "PublicView",
                component: PublicView,
            },
        ],
    },
    {
        path: "/auth",
        name: "AuthorizationView",
        component: AuthorizationView,
        meta: {
            requiresAuth: true,
        },
    },
    {
        path: "/plug",
        name: "PlugView",
        component: PlugView,
    },
];

При этом у меня идет отслеживание (пока что только) agreement:

const agreement = computed(() => store.state.agreement);

Также у меня есть хук:

router.beforeEach((to, from, next) => {
    if (to.meta.requiresAuth && !agreement.value) {
        next({ name: "TermsOfUseView" });
    } else if (
        agreement.value &&
        (!store.state.user.google_token || !store.state.user.apple_token)
    ) {
        next({ name: "AuthorizationView" });
    } else if (store.state.user.token && to.meta.isGuest) {
        next({ name: "HomeView" });
    } else {
        next();
    }
});

На странице TermsOfUse при нажатии на I agree изменяется значение agreement. И после этого возникает ошибка:

Detected a possibly infinite redirection in a navigation guard when going from "/terms-of-use" to "/auth". Aborting to avoid a Stack Overflow.

Каким образом будет лучше настроить данный роутинг, который будет зависеть от динамических значений?

Поправка №1

Я подумала ввести переменную с state, значение которой мы изменим, если пользователь вошел в аккаунт google или apple. Таким образом у нас есть три переменные, в зависимости от значения которых мы будем перенаправлять наши пути: tokenAuth, agreement, guest.
  • Вопрос задан
  • 195 просмотров
Решения вопроса 1
@AnastasiyaLebedevich Автор вопроса
Начинающий frontend developer
После долгих неудачных попыток пришла к такому результату. Код, на мой взгляд, кажется несколько нагроможденным - возможно кто-то предложит что-то более изящное или просто более удобный/подходящий вариант - но он работает (вроде как):
router.beforeEach((to, from, next) => {
	const tokenAuth = computed(() => store.state.Auth.authToken);
	const agreement = computed(() => store.state.Auth.nativeData.agreement);
	const guest = computed(() => store.state.Auth.guest);

	if (
		to.meta.requiresAuth &&
		!Boolean(tokenAuth.value) &&
		!agreement.value &&
		!guest.value
	) {
		next({ name: 'TermsOfUseView' });
	} else if (
		to.meta.isGuest &&
		!Boolean(tokenAuth.value) &&
		agreement.value &&
		!guest.value
	) {
		next({ name: 'AuthorizationView' });
	} else if (
		to.meta.isGuest &&
		Boolean(tokenAuth.value) &&
		agreement.value &&
		guest.value
	) {
		next({ name: 'HomeView' });
	} else {
		next();
	}
});
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
scoffs
@scoffs
Fullstack | C# | Student
Возможное решение
router.beforeEach((to, from, next) => {
  const isAgreementAccepted = agreement.value;
  const isUserLoggedIn = Boolean(store.state.user.token);

  if (to.meta.requiresAuth && !isAgreementAccepted) {
    // Если требуется аутентификация и соглашение не принято,
    // перенаправляем на страницу TermsOfUseView
    next({ name: "TermsOfUseView" });
  } else if (to.name === "TermsOfUseView" && isAgreementAccepted) {
    // Если пользователь уже принял соглашение,
    // перенаправляем его на другую страницу, например, HomeView
    next({ name: "HomeView" });
  } else if (to.meta.requiresAuth && !isUserLoggedIn) {
    // Если требуется аутентификация и пользователь не вошел в систему,
    // перенаправляем на страницу AuthorizationView
    next({ name: "AuthorizationView" });
  } else if (to.meta.isGuest && isUserLoggedIn) {
    // Если пользователь вошел в систему, но на страницу доступа только для гостей,
    // перенаправляем на другую страницу, например, HomeView
    next({ name: "HomeView" });
  } else {
    // В остальных случаях просто продолжаем навигацию
    next();
  }
});
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы