📚 Nuxt 摄影项目(二):基础组件搭建 & 主题切换功能实现 & Nuxt UI 使用
本篇将继续搭建摄影网站的基础框架,主要内容包含:
- 创建头部(Header)与底部(Footer)布局组件
- 使用 Nuxt UI 的基础组件
- 实现主题切换功能(浅色 / 深色 / 跟随系统)
- 配置默认布局
🔗 系列文章导航
| 章节 | 链接 |
|---|---|
| (一)项目搭建 | juejin.cn/post/757213… |
| (二)基础组件 & 主题切换(当前) | juejin.cn/post/757213… |
🧱 1. 新增头部组件(Header)
创建文件:
app/components/layouts/header.vue
内容如下:
<script setup lang="js">
import {useTheme} from "~/composables/useTheme.js";
const route = useRoute()
const themeInfo = ref(null)
const colorMode = useColorMode()
const {setDark, setLight, setSystem} = useTheme()
const themes = ref([
{icon: 'i-lucide-monitor', label: '跟随系统', value: 'system', setter: setSystem},
{icon: 'i-lucide-sun', label: '浅色模式', value: 'light', setter: setLight},
{icon: 'i-lucide-moon', label: '深色模式', value: 'dark', setter: setDark,}
])
const themeList = computed(() =>
themes.value.map(theme => ({
...theme,
onSelect: () => {
themeInfo.value = theme
theme.setter()
}
}))
)
const menuItems = computed(() =>
[
{label: "首页 🏠", to: "/", active: route.path === '/'},
{label: "画廊 🎨", to: "/gallery", active: route.path.startsWith('/gallery')},
{label: "足迹 👣", to: "/map", active: route.path.startsWith('/map')},
{label: "关于我 👴", to: "/about", active: route.path.startsWith('/about')},
]
)
onMounted(() => {
themeInfo.value = themeList.value.find(theme => theme.value === colorMode.preference)
console.log(themeList.value)
})
</script>
<template>
<UHeader>
<template #title>
LOGO
</template>
<UNavigationMenu :items="menuItems" type="single"/>
<template #right>
<UDropdownMenu v-if="themeInfo" :items="themeList">
<UTooltip text="主题">
<UButton
:icon="themeInfo.icon" color="neutral" variant="ghost"/>
</UTooltip>
</UDropdownMenu>
</template>
</UHeader>
</template>
<style scoped lang="scss"></style>
🧱 2. 新增底部组件(Footer)
创建文件:
app/components/layouts/footer.vue
内容:
<script setup lang="js">
</script>
<template>
<UFooter>
版权所有 Copyright(©)2009-2022上海博卡软件科技有限公司
</UFooter>
</template>
<style scoped lang="scss"></style>
🧱 3. 创建默认布局 Layout(default.vue)
创建文件:
app/layouts/default.vue
内容(注意路径是否与你实际一致):
<script setup lang="js">
import Header from "~/components/base/Header.vue";
import Footer from "~/components/base/Footer.vue";
</script>
<template>
<UApp>
<Header/>
<UMain>
<NuxtPage/>
<Footer/>
</UMain>
</UApp>
</template>
<style scoped lang="scss"></style>
⚠️ 如果你的目录是
components/layouts,记得把路径修改为:
~/components/layouts/Header.vue
🧱 4. 修改根组件 app.vue
<template>
<NuxtLayout>
<NuxtPage/>
</NuxtLayout>
</template>
保持默认即可。
🧱 5. 测试 Nuxt UI 组件是否工作正常
编辑:
app/pages/index.vue
内容:
<script setup lang="js"></script>
<template>
<div class="component">
<UButton>Button</UButton>
</div>
</template>
<style scoped lang="scss"></style>
正常显示按钮说明 Nuxt UI 工作正常。
🧱 6. 实现主题切换逻辑(useTheme.js)
新增文件:
app/composables/useTheme.js
内容:
export function useTheme() {
const colorMode = useColorMode()
const setLight = () => {
colorMode.preference = 'light'
}
const setDark = () => {
colorMode.preference = 'dark'
}
const setSystem = () => {
colorMode.preference = 'system'
}
return {setLight, setDark, setSystem,}
}
到此为止,主题切换已经可以完整工作 🎉
🎉 最终效果
你现在已经拥有:
✔ 一个全局头部(Header)
✔ 一个全局底部(Footer)
✔ 一个默认布局(default)
✔ 可正常显示的 Nuxt UI 组件
✔ 可切换浅色 / 深色 / 跟随系统 的主题功能
整个摄影网站的基础架构已经完成!