我在我的一个项目中使用 Nuxt 3 并为其创建了一个 404 页面。我的项目中有两个布局。我的默认布局(default.vue)包括页脚和页眉等常规组件。在我的自定义 404 页面中,我想使用默认布局(default.vue)。
但是,当我定义我的 404 组件时,如下所示:
<script setup>
const error = useError();
console.log({error})
const handleError = () => {
clearError({
redirect: '/',
});
};
</script>
<template>
<NuxtLayout>
<div class="prose">
<h1>Dang</h1>
<p>
<strong>{{ error.message }}</strong>
</p>
<p>It looks like something broke.</p>
<p>Sorry about that.</p>
<p>
Go back to your
<a @click="handleError">
dashboard.
</a>
</p>
</div>
</NuxtLayout>
</template>
由于标头组件中使用了 prop,我收到错误。
无法读取未定义的属性(读取“modeCheckout”)
这是我的代码:
布局/default.vue
<script setup>
import {inject,watch} from 'vue';
const { alert, setAlert } = inject('alert')
</script>
<template>
<div class="page-wrapper">
<div class="content-wrapper" >
<Alert :alert="alert"/>
<AppBar/>
<div class="main-wrapper">
<slot></slot>
</div>
<WebsiteFooter/>
</div>
</div>
</template>
<style lang="scss">
.page-wrapper{
@include d-flex(row,flex-start,flex-start);
min-height: 100%;
.content-wrapper{
width: 100%;
height: 100%;
.main-wrapper{
margin-top: 10px;
border-radius: 4px;
padding: 16px;
}
}
}
</style>
AppBar.vue
<script setup>
import {ref,inject} from 'vue';
const props = defineProps({
modeCheckout:{type:Boolean,default:false}
})
const isClickedHamMenu = ref(false);
const {basketItemCount} = inject('basketItemCount')
const toggleMenu = () =>{
isClickedHamMenu.value = !isClickedHamMenu.value
let menu = document.querySelector('.menu-wrapper');
if(isClickedHamMenu.value){
menu.classList.add('slide-menu-ttb');
if(menu.classList.contains('slide-menu-btt')){
menu.classList.remove('slide-menu-btt')
}
}
else{
menu.classList.add('slide-menu-btt');
if(menu.classList.contains('slide-menu-ttb')){
menu.classList.remove('slide-menu-ttb')
}
setTimeout(()=>{
menu.classList.remove('slide-menu-btt');
},150)
}
}
</script>
<template>
<div class="container">
<div class="app-bar-wrapper p10">
<NuxtLink class="logo-wrapper" to="/">
<img src="/logo.png" alt="Artisan">
</NuxtLink>
<div v-if="!props.modeCheckout" class="search-wrapper">
<Icon name="mdi:magnify" color="black" size="24"/>
<input type="text" autocomplete="off" spellcheck="false" placeholder="Search">
</div>
<div class="app-bar-actions">
<div v-if="!props.modeCheckout" :class="['hamburger-wrapper', isClickedHamMenu ? 'close' : '']" @click="toggleMenu">
<span class="child-1"></span>
<span class="child-2"></span>
<span class="child-3"></span>
</div>
<div class="icon-wrapper">
<Button
icon="mdi:account"
fontSize="24px"
fontColor="#000"
text
hoveredBackground="transparent"
background="transparent"
hoveredColor="#000"
padding="0"
/>
</div>
<NuxtLink to="/cart" class="icon-wrapper">
<Button
icon="mdi:cart-outline"
fontSize="24px"
fontColor="#000"
text
hoveredBackground="transparent"
background="transparent"
hoveredColor="#000"
padding="0"
/>
<div v-if="basketItemCount>0" class="cart-item-count">
{{basketItemCount}}
</div>
</NuxtLink>
</div>
</div>
<Menu v-if="!props.modeCheckout"/>
</div>
</template>
应用程序.vue
<script setup>
import {ref} from 'vue'
const alert = ref({});
const basketItemCount = ref(0)
const route = useRoute()
const setAlert = obj => {
alert.value = obj;
}
const setBasketItemCount = () =>{
basketItemCount.value = JSON.parse(window.localStorage.getItem('basket-items'))?.reduce((a,b)=>a+b.quantity,0) || 0
}
onMounted(() => {
setBasketItemCount();
})
provide('basketItemCount',{basketItemCount,setBasketItemCount})
provide('alert', {alert,setAlert});
</script>
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
在Nuxt 3中,您可以通过在layouts目录中定义error.vue文件来创建自定义404页面。该文件将用作错误页面(包括 404 页面)的默认布局。 文档
设置方法如下:
创建一个layouts/error.vue文件:这将成为所有错误页面的布局。
为404错误添加自定义逻辑:在layouts/error.vue中,您可以检查error.statusCode并根据它有条件地渲染内容。
// layouts/error.vue
<template>
<div>
<h1 v-if="error?.statusCode === 404">Page Not Found</h1>
<p v-else>Oops, something went wrong.</p>
<!-- Additional layout components or links can go here -->
</div>
</template>
<script setup>
defineProps({
error: Object
})
</script>
通过此设置,Nuxt 3 将使用 error.vue 来处理任何错误,并且 statusCode 检查可让您专门针对 404 错误自定义内容。