我正在使用 Nuxt3 和 Pinia 玩。
我想要两种布局:一种用于访客用户,另一种用于经过身份验证的用户。
应用程序.vue
<script lang="ts" setup>
</script>
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
布局.global.ts
import {storeToRefs} from "pinia";
import {useAuthStore} from "~/store/auth";
export default defineNuxtRouteMiddleware((to) => {
const authStore = useAuthStore();
const {authenticated} = storeToRefs(authStore);
const layout = computed(() => {
return authenticated.value ? "authenticated-layout" : "default-layout";
});
setPageLayout(layout)
})
我所做的每次测试都出现相同的错误:
chunk-RAKT47ZN.js:1449 [Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core
at <NuxtLayoutProvider layoutProps= {ref: RefImpl} key="authenticated-layout" name="authenticated-layout" ... >
at <NuxtLayout>
at <App key=3 >
at <NuxtRoot>
warn2 @ chunk-RAKT47ZN.js:1449
logError @ chunk-RAKT47ZN.js:1623
handleError @ chunk-RAKT47ZN.js:1615
callWithErrorHandling @ chunk-RAKT47ZN.js:1567
flushJobs @ chunk-RAKT47ZN.js:1763
Promise.then (async)
queueFlush @ chunk-RAKT47ZN.js:1676
queueJob @ chunk-RAKT47ZN.js:1670
(anonymous) @ chunk-RAKT47ZN.js:7208
triggerEffect @ chunk-RAKT47ZN.js:614
triggerEffects @ chunk-RAKT47ZN.js:604
triggerRefValue @ chunk-RAKT47ZN.js:1211
(anonymous) @ chunk-RAKT47ZN.js:1371
triggerEffect @ chunk-RAKT47ZN.js:614
triggerEffects @ chunk-RAKT47ZN.js:599
triggerRefValue @ chunk-RAKT47ZN.js:1211
set value @ chunk-RAKT47ZN.js:1255
finalizeNavigation @ vue-router.js:2409
(anonymous) @ vue-router.js:2319
Promise.then (async)
pushWithRedirect @ vue-router.js:2287
push @ vue-router.js:2213
login @ login.vue:19
await in login (async)
(anonymous) @ chunk-RAKT47ZN.js:10436
callWithErrorHandling @ chunk-RAKT47ZN.js:1565
callWithAsyncErrorHandling @ chunk-RAKT47ZN.js:1573
invoker @ chunk-RAKT47ZN.js:9397
chunk-RAKT47ZN.js:9157 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'parentNode')
at parentNode (chunk-RAKT47ZN.js:9157:30)
at ReactiveEffect.componentUpdateFn [as fn] (chunk-RAKT47ZN.js:7175:11)
at ReactiveEffect.run (chunk-RAKT47ZN.js:423:19)
at instance.update (chunk-RAKT47ZN.js:7212:52)
at updateComponent (chunk-RAKT47ZN.js:7039:18)
at processComponent (chunk-RAKT47ZN.js:6974:7)
at patch (chunk-RAKT47ZN.js:6436:11)
at patchSuspense (chunk-RAKT47ZN.js:2562:7)
at Object.process (chunk-RAKT47ZN.js:2481:7)
at patch (chunk-RAKT47ZN.js:6461:16)
parentNode @ chunk-RAKT47ZN.js:9157
componentUpdateFn @ chunk-RAKT47ZN.js:7175
run @ chunk-RAKT47ZN.js:423
instance.update @ chunk-RAKT47ZN.js:7212
updateComponent @ chunk-RAKT47ZN.js:7039
processComponent @ chunk-RAKT47ZN.js:6974
patch @ chunk-RAKT47ZN.js:6436
patchSuspense @ chunk-RAKT47ZN.js:2562
process @ chunk-RAKT47ZN.js:2481
patch @ chunk-RAKT47ZN.js:6461
componentUpdateFn @ chunk-RAKT47ZN.js:7171
run @ chunk-RAKT47ZN.js:423
instance.update @ chunk-RAKT47ZN.js:7212
callWithErrorHandling @ chunk-RAKT47ZN.js:1565
flushJobs @ chunk-RAKT47ZN.js:1763
chunk-RAKT47ZN.js:7520 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'subTree')
at move (chunk-RAKT47ZN.js:7520:28)
at move (chunk-RAKT47ZN.js:7520:7)
at Object.resolve (chunk-RAKT47ZN.js:2789:11)
at chunk-RAKT47ZN.js:2912:20
我对 Vue 还很陌生(我主要使用 React)。
我错过了什么吗? (SSR?)。 Vue.js 中有另一种方法可以做到这一点吗?
我认为您不需要在您的情况下使用计算。像这样的简单验证就可以了。
这是如何使用动态布局内容的示例。
~/middleware/layout.global.ts
export default defineNuxtRouteMiddleware(() => {
const authenticated = false
if (authenticated) {
return setPageLayout('authenticated')
} else {
return setPageLayout('default')
}
})
如果您将
authenticated
设置为 true
,它会将布局更改为 authenticated
。
创建布局
~/layouts/authenticated.vue
<template>
<div>
<h1>Authenticated</h1>
<div>
<slot />
</div>
</div>
</template>
~/middleware/default.vue
<template>
<div>
<h1>Default Layout</h1>
<div>
<slot />
</div>
</div>
</template>
设置页面布局
app.vue
<template>
<div>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</div>
</template>
~/pages/index.vue
<script lang="ts" setup>
definePageMeta({
layout: 'authenticated'
})
</script>
<template>
<div>
<h1>Home page</h1>
</div>
</template>
已测试,有效。