gpt4 book ai didi

Nuxt 3, unable to find the error: A composable that requires access to the Nuxt instance was called outside of a plugin(Nuxt 3,找不到错误:在插件外部调用了需要访问Nuxt实例的Composable)

转载 作者:bug小助手 更新时间:2023-10-25 16:36:17 53 4
gpt4 key购买 nike



I have a composable that returns a function to verify auth and refresh token within an interval of 5 seconds. Both utilizing Nuxt's useCookie utility function to perform the logic behind it.

我有一个Composable,它返回一个函数,在5秒的间隔内验证身份验证和刷新令牌。两者都利用Nuxt的useCookie实用程序函数来执行其背后的逻辑。


At first, it works. But then sometimes, when the token expired, it broke and throw me an error shown on the error screen. This is the error:

起初,它是有效的。但有时,当令牌到期时,它会损坏,并抛出错误屏幕上显示的错误。这是错误:



500

[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at `https://nuxt.com/docs/guide/concepts/auto-imports#using-vue-and-nuxt-composables`.

at Module.useAsyncData (./node_modules/nuxt/dist/app/composables/asyncData.js:26:38)
at useFetch (./node_modules/nuxt/dist/app/composables/fetch.js:53:43)
at refreshToken (./composables/useRepository.ts:206:35)
at verifyAuth (./composables/useRepository.ts:250:31)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async setup (./layouts/dashboard.js:35:87)


I've read my code implementation many times but cannot find where the problem is. Please help me find the error.

我已经多次阅读我的代码实现,但找不到问题所在。请帮我找出错误。


This is the piece of codes that causing this error to be happen.

这是导致该错误发生的一段代码。


useRepository.ts

UseRepository.ts


export const useRepository = () => {
const config = useRuntimeConfig()
const cookie = useCookie<LoginResponse | null>('auth')

const refreshToken = async () => {
const { data, error } = await useFetch<RefreshTokenResponse>(
`/api/jwt-auth/jwt/refresh/`,
{
baseURL: config.public.apiUrl,
method: 'POST',
query: { format: 'json' },
body: { refresh: cookie.value?.refresh },
},
)

if (error.value) {
const { status } = error.value
if (status === 400 || status === 401 || status === 403) {
cookie.value = null
navigateTo('/login?redirect=session-expired')
return false
}
}

if (!cookie.value) {
console.warn(
'You have issued a refresh token but no users has signed in to this session, check your code implementation.',
)
return false
}

if (!data.value || !data.value.access) {
console.warn(
'Server returns no access token, users will be forcefully kicked out to the login page. Please talk to your server administrator.',
)
return false
}

cookie.value = { ...cookie.value, access: data.value.access }
return true
}

const verifyAuth = async (timer?: ReturnType<typeof setInterval>) => {
const { error, execute: refetch } = await useFetch<VerifyAuthResponse>(
`/api/jwt-auth/jwt/verify/`,
{
baseURL: config.public.apiUrl,
method: 'POST',
query: { format: 'json' },
body: { token: cookie.value?.access },
},
)

if (error.value) {
const data = await error.value.data
if (data && data.code === 'token_not_valid') {
const success = await refreshToken()
if (!success) {
if (timer) {
console.log('clearing auth cookie')
clearInterval(timer)
}
cookie.value = null
return navigateTo('/login?redirect=session-expired')
} else {
console.log('refetching')
await refetch()
}
}
}
}

return {
verifyAuth,
refreshToken,
}
}


dashboard.vue

Dashboard.vue


<script setup lang="ts">
useHead({
htmlAttrs: {
lang: 'id',
},
titleTemplate(title) {
return title
? `${title} - MyApp`
: 'My Branding Punchline - MyApp'
},
bodyAttrs: {
class:
'scrollbar scrollbar-thumb-primary scrollbar-track-primary/10 scrollbar-thin scroll-smooth',
},
})

const { verifyAuth } = useRepository()
await verifyAuth()

const timer = ref<ReturnType<typeof setInterval>>()
const stopVerifyingAuth = () => {
if (timer.value) clearInterval(timer.value)
}

const continuouslyVerifyAuth = () => {
timer.value = setInterval(() => {
verifyAuth(timer.value)
}, 5000)
}

onActivated(() => continuouslyVerifyAuth())
onDeactivated(() => stopVerifyingAuth())
onUnmounted(() => stopVerifyingAuth())

const windowFocus = useWindowFocus()
watch(windowFocus, async (isFocus) => {
if (isFocus) {
await verifyAuth(timer.value)
continuouslyVerifyAuth()
} else {
stopVerifyingAuth()
}
})
</script>

<template>
<main class="box-border antialiased text-black overflow-x-hidden">
<div class="h-screen flex items-start">
<TheSidebar />
<div
class="w-full h-full overflow-y-auto scrollbar-thumb-primary scrollbar-track-primary/10 scrollbar-thin scroll-smooth"
>
<slot />
</div>
</div>
</main>
</template>


更多回答
优秀答案推荐

After days of debugging, it turns out that my implementation should not be put inside the layouts file.

经过几天的调试,我发现我的实现不应该放在布局文件中。


I don't know why.

我也不知道原因。


My current solution is to create a wrapper component to be used on each page.

我目前的解决方案是创建一个在每个页面上使用的包装组件。


So now my code look like this

所以现在我的代码如下所示


layouts/dashboard.vue

布局/仪表板.vue


<script setup lang="ts">
useHead({
htmlAttrs: {
lang: 'id',
},
titleTemplate(title) {
return title
? `${title} - MyApp`
: 'My Branding Punchline - MyApp'
},
bodyAttrs: {
class:
'scrollbar scrollbar-thumb-primary scrollbar-track-primary/10 scrollbar-thin scroll-smooth',
},
})
</script>

<template>
<main class="box-border antialiased text-black overflow-x-hidden">
<div class="h-screen flex items-start">
<TheSidebar />
<div
class="w-full h-full overflow-y-auto scrollbar-thumb-primary scrollbar-track-primary/10 scrollbar-thin scroll-smooth"
>
<slot />
</div>
</div>
</main>
</template>

components/DashboardContent.vue

组件/仪表板内容.vue


<script setup lang="ts">
const { verifyAuth } = useRepository()
await verifyAuth()

const timer = ref<ReturnType<typeof setInterval>>()
const stopVerifyingAuth = () => {
if (timer.value) clearInterval(timer.value)
}

const continuouslyVerifyAuth = () => {
timer.value = setInterval(() => {
verifyAuth(timer.value)
}, 5000)
}

onActivated(() => continuouslyVerifyAuth())
onDeactivated(() => stopVerifyingAuth())
onUnmounted(() => stopVerifyingAuth())

const windowFocus = useWindowFocus()
watch(windowFocus, async (isFocus) => {
if (isFocus) {
await verifyAuth(timer.value)
continuouslyVerifyAuth()
} else {
stopVerifyingAuth()
}
})
</script>

<template>
<div>
<slot />
</div>
</template>

pages/dashboard/index.vue

页面/仪表板/index.vue


<script setup lang="ts">
definePageMeta({ middleware: ['auth'], layout: 'dashboard' })
</script>

<template>
<DashboardContent>
Hello World!
</DashboardContent>
</template>

更多回答

53 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com