中间件中 useRoute 的问题

问题描述 投票:0回答:1

当使用在中间件内使用

useRoute
的可组合项时,我收到此警告:“[nuxt] 在中间件内调用 useRoute 可能会导致误导结果。相反,使用传递给中间件的 (to, from) 参数来访问新路由和旧路由。'

我尝试了这里的解决方案:https://github.com/nuxt-modules/i18n/issues/2064和这里Nuxt i18n 在中间件中调用 useRoute 可能会导致误导性结果,但它们不适用于我。我试图了解这是否是一个需要等待修复的错误,或者是否有实际的解决方案。我在

useRoute
内部使用
useStoreAuth()
,但不在
checkSession
内部使用。由于我在中间件中添加了
useStoreAuth
,所以它说我无法使用
useRoute
。为使用
signIn
useRoute
函数创建单独的可组合项将不起作用,因为我需要在
signedIn
useStoreAuth
函数中访问来自
checkSession
signIn
引用。此外,我需要在
checkSession
中使用
signIn
,这意味着如果我创建一个名为
useStoreSession
的单独可组合项并将其添加到中间件,它还将包含
useStoreAuth
useRoute

export default defineNuxtRouteMiddleware(async (to, _from) => {
    const { signedIn, checkSession } = useStoreAuth();

    await checkSession();

    if (!signedIn.value && to.path.startsWith('/profile')) {
        return navigateTo(`/sign-in?redirect=${encodeURIComponent(to.path)}`);
    }
    if (signedIn.value && to.path === '/sign-in') {
        return navigateTo('/');
    }
});

我在可组合项中使用

useRoute
的方式:

export const useStoreAuth = () => {
    const route = useRoute();
    const signIn = async (signInData: SignInData) => {
        const { apiBase } = useRuntimeConfig().public;
        state.pending = true;
        state.error = null;
        state.successMessage = null;

        const res = await fetch(`${apiBase}/signIn`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(signInData),
        });

        try {
            if (res.ok) {
                await checkSession();
                if (state.signedIn) {
                  if (route.query.redirect) {
                      await navigateTo(`${route.query.redirect}`);
                  } else {
                      await navigateTo(`${route.query.redirect}` || '/');
                  }

                  state.successMessage = 'Signed in successfully';
              } else {
                    state.error = 'Error signing in';
                }
            } else if (res.status === 400) {
                state.error = 'Validation error';
            } else {
                const resData = await res.json();
                state.error = resData.message || "User doesn't exist";
            }
        } catch (err) {
            state.error = `An unexpected error occurred ${err.message}`;
        } finally {
            state.pending = false;
        }
    };


    return {
        ...toRefs(state),
        signIn,
    };
};

寻找可能的解决方案。

javascript vue.js vuejs3 nuxt.js nuxt3.js
1个回答
0
投票

为了在 Pinia 存储中可靠地使用可组合项,应保证在允许组合项时进行初始化,即第一个

useStore()
调用应在组件的设置中发生,而不是更早。如果 store 用于其他地方(例如路由器钩子),则这是不可行的,第一次导航可以在创建组件实例之前发生在 Vue 中。

更实用的方法是在可组合项可访问时注入具有可组合结果的商店,例如在根组件中:

store.route = useRoute()

在这种情况下,这就是解决方案,因为路由器挂钩中仅使用

checkSession
。只要不使用
route
,此时后者是否未初始化也没关系。如果在此之前使用
route
,这将是一个问题,可能的解决方法是允许使用它的方法 (
signIn
) 选择性地通过参数接受路由对象。所以它可以用作路由器钩子中的
store.signIn(data, to)
,而
signIn
可以用作
(route.value ?? routeArg).query.redirect
。再说一次,这不是问题,但如果是的话,这就是解决问题的方法。

这也表明可能存在设计问题,存储包含可能属于路由器的路由逻辑。在这种情况下,

sign-in
路由和路由器钩子可以处理
redirect
参数和可能的重定向,并且根组件可以对
store.signedIn
状态的变化做出反应,而存储将负责不依赖于特定的逻辑。路线实施。

© www.soinside.com 2019 - 2024. All rights reserved.