前言
今天开发项目的 Footer 布局,这里我们参考 Nuxt-UI 官网的布局。
需求拆分
- 准备好域名备案号和 icp 图标
- 底部社交按钮链接或其他链接
- AppFooter 组件开发
Footer 布局
新建 components/AppFooter.vue 文件:
js 代码:<template> <footer class="fixed bottom-0 w-full"> <UDivider :avatar="{ src: '/logo.svg' }" /> <div class="flex justify-between items-center px-4 md:px-8 lg:px-32 py-3 max-sm:flex-col -mt-2.5"> <!-- icp 备案 --> <ULink to="https://beian.miit.gov.cn/#/Integrated/index" target="_blank" active-class="text-primary" inactive-class="text-sm text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" > <div class="flex items-center gap-2"> <NuxtImg src="/icp.png" alt="粤ICP备2023007649号-3" class="w-4" /> 粤ICP备2023007649号-3 </div> </ULink> <!-- 社交图标 --> <div class="max-sm:order-first"> <!-- github --> <SocialButton icon="i-ri-github-line" url="https://github.com/baiwumm" tip="Github" /> <!-- 微信 --> <SocialButton icon="i-ri-wechat-line" url="https://wechat.baiwumm.com/" tip="微信" /> <!-- 电子邮箱 --> <SocialButton icon="i-ri-mail-line" url="mailto:baiwumm@foxmail.com" tip="Email" /> <!-- 博客 --> <SocialButton icon="i-ri-quill-pen-line" url="https://baiwumm.com" tip="博客" /> </div> </div> </footer> </template>
layouts/default.vue 文件配置组件:
html 代码:<template> <div> <!-- header --> <AppHeader /> <!-- main --> <slot /> <!-- footer --> <AppFooter /> </div> </template>
这里我们顺便给 AppColorMode 组件加个切换过渡动画,让网站丰富一点:
js 代码:<script setup lang="ts"> const colorMode = useColorMode() // 切换模式 const setColorMode = () => { colorMode.value = colorMode.value === 'dark' ? 'light' : 'dark' } // 判断是否支持 startViewTransition API const enableTransitions = () => 'startViewTransition' in document && window.matchMedia('(prefers-reduced-motion: no-preference)').matches // 切换动画 async function toggleDark({ clientX: x, clientY: y }: MouseEvent) { const isDark = colorMode.value === 'dark' if (!enableTransitions()) { setColorMode() return } const clipPath = [ `circle(0px at $px ${y}px)`, `circle(${Math.hypot( Math.max(x, innerWidth - x), Math.max(y, innerHeight - y) )}px at $px ${y}px)` ] await document.startViewTransition(async () => { setColorMode() await nextTick() }).ready document.documentElement.animate( { clipPath: !isDark ? clipPath.reverse() : clipPath }, { duration: 300, easing: 'ease-in', pseudoElement: `::view-transition-${!isDark ? 'old' : 'new'}(root)` } ) } </script> <template> <UTooltip :text="`切换${$colorMode.value === 'dark' ? '白天' : '黑夜'}模式`"> <UButton :icon="$colorMode.value === 'dark' ? 'i-heroicons-moon-solid' : ' i-heroicons-sun-solid'" size="sm" variant="ghost" class="text-gray-700 dark:text-gray-200 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-800" @click="toggleDark" /> </UTooltip> </template> <style> ::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; } ::view-transition-old(root), .dark::view-transition-new(root) { z-index: 1; } ::view-transition-new(root), .dark::view-transition-old(root) { z-index: 9999; } </style>
最终效果
总结
这个篇章内容比较简单,下一篇开发主体内容。
好了,今天就到这吧!
Github 仓库:dream-site
线上预览:dream-site.cn