背景
在最近写的文章中,有小伙伴可能搞不明白,Nuxt3
中 怎么去设计自己的Layout
导致在写代码的时候,可能很困惑, 今天用一个实际的案例讲解一下
我们以官网为例,有基本的布局, 有登录,有菜单等
问题
他们疑惑的3个问题是:
- 这样的layout 应该怎么写,代码怎么组织?
- 菜单的高亮怎么处理?
- 登录,退出 逻辑应该写在哪里,layout还是具体的页面?
实现1:layout怎么写
应该在
layouts
目录中创建一个新的 layout, 如果项目比较简单,那就创建一个default.vue
作为默认的layout区别在于:
default.vue
这个layout 在写页面的时候,是不用指定NuxtLayout
的name
如果项目比较大,会存在多个layout的情况,我们这里创建一个新的, layout-3.vue
layouts/layout-3.vue
<template>
<div>
<top-header></top-header>
<div class="main-container">
<slot></slot>
</div>
</div>
</template>
<style lang="scss" scoped>
.main-container {
max-width: 1000px;
margin-left: auto;
margin-right: auto;
}
</style>
layout的问题已经解决了, 现在增加 顶部菜单组件
Nuxt3中写在 根目录
里面的 components
目录里面的组件是全局组件
, 所以这里没有 引入 top-header 这个文件
/components/top-header.vue
<template>
<div class="top-header">
<div class="header-layout">
<div class="menu-list">
<div
class="menu-item"
:class="{ 'active-menu-item': isActive === index }"
v-for="(item, index) in menuList"
:key="index"
>
<NuxtLink :to="item.to">{{ item.text }}</NuxtLink>
</div>
</div>
<div class="logout" @click="onLogin">{{ isLogin ? '退出' : '登录' }}</div>
</div>
</div>
</template>
<script setup>
const route = useRoute()
const useToken = useCookie('token')
const isLogin = computed(() => {
return useToken.value
})
const isActive = computed(() => {
let index = menuList.value.findIndex((item) => item.to === route.path)
return index
})
const menuList = ref([
{
text: '功能',
to: '/page-header/function'
},
{
text: '解决方案',
to: '/page-header/solution'
},
{
text: '资源',
to: '/page-header/resource'
}
])
const onLogin = () => {
if (!useToken.value) {
// 模拟登录
useToken.value = Date.now()
} else {
// 模拟退出
useToken.value = ''
}
}
</script>
<style lang="scss" scoped>
.top-header {
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
font-weight: 500;
height: 68px;
.menu-list {
flex: 1;
flex-shrink: 0;
display: flex;
justify-content: center;
gap: 20px;
}
a {
text-decoration: none;
color: #fff;
}
.active-menu-item {
a {
color: #cb5a9c;
}
}
}
.header-layout {
max-width: 1000px;
flex: 1;
display: flex;
justify-content: space-between;
}
.logout {
color: #fff;
cursor: pointer;
}
</style>
实现2:菜单高亮怎么处理
上面代码,已经看到了,菜单的高亮是拿到当前的path, 去匹配这个path 就设置了菜单的高亮
我们从 “功能”页面切换到 “解决方案” 页面, 是完整的页面切换,所有,在切换过去,isActive
会重新执行; 这样就实现了菜单的高亮。
实现3:登录登出逻辑怎么写
需要借助 cookie 或者 localStorage 或者 sessionStorage 去判断登录状态; 当然这里做的比较基础,已经能最小化处理了,登录,退出 的一些逻辑问题
所以登录,退出逻辑是写在 top-header组件里面的; 当然事件项目中会有调用接口,逻辑判断,浏览器 Storage或者 cookie中的数据清空操作。
页面代码
我们看看具体的页面,以 pages/page-header/function.vue
功能页面为例
<template>
<NuxtLayout name="layout-3">
<div class="page-container">功能页面</div>
</NuxtLayout>
</template>
<script setup></script>
<style lang="scss" scoped>
.page-container {
background-color: pink;
}
</style>
目录结构
- components
- top-header.vue
- pages/
- page-header/
- index.vue
- function.vue
- resource.vue
- solution.vue
- layouts/
- layout-3.vue
- package.json
上面从 layout的创建, 布局编写, 登录,退出 逻辑组织 完整的引导了一个新手掌握 layout;
希望对各位Nuxt3新手看官有帮助~ 蟹蟹 😊😊😊