Nuxt3 实战 (六):Footer 底部布局

简介: 这篇文章介绍了开发项目的Footer布局,参考了Nuxt-UI官网的布局。文章从需求拆分开始,讲解了准备工作和组件开发的过程。最后展示了最终效果,并进行了简单的总结,指出下一篇将讨论主体内容的开发。文末提供了Github仓库和线上预览的链接。

前言

今天开发项目的 Footer 布局,这里我们参考 Nuxt-UI 官网的布局。

需求拆分

  1. 准备好域名备案号和 icp 图标
  2. 底部社交按钮链接或其他链接
  3. 布局组件开发

Footer 布局

  1. 新建 components/AppFooter.vue 文件:
    <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>
    
  2. layouts/default.vue 文件配置组件:
    <template>
    <div>
    <!-- header -->
    <AppHeader />
    <!-- main -->
    <slot />
    <!-- footer -->
    <AppFooter />
    </div>
    </template>
    
  3. 这里我们顺便给 AppColorMode 组件加个切换过渡动画,让网站丰富一点:

    <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 ${
           x}px ${
           y}px)`,
      `circle(${
           Math.hypot(
        Math.max(x, innerWidth - x),
        Math.max(y, innerHeight - y)
      )}px at ${
           x}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>
    

最终效果

iwf0h2yzwd7zbqojg9e2q6iag6yvvdc7.gif

总结

这个篇章内容比较简单,下一篇开发主体内容。

好了,今天就到这吧!

Github 仓库dream-site

线上预览dream-site.cn

相关文章
|
数据采集 前端开发 JavaScript
我是如何使用 Next.js14 + Tailwindcss 重构个人项目的
这篇文章介绍了作者在学习React和Nest时受到大佬imsyy项目DailyHot的启发,基于React开发了一个项目,并因为这个项目获得了少量流量而进行了优化。作者随后因为想要优化SEO和深入学习Next.js14,决定重构这个项目。文章详细介绍了项目的信息、特性、演示图、运行环境、Vercel本地部署步骤以及责任声明。作者还感谢了为本项目提供支持与灵感的项目,并承诺会记录下开发过程中遇到的问题及解决方法以帮助他人。
290 0
我是如何使用 Next.js14 + Tailwindcss 重构个人项目的
|
10月前
|
资源调度
Vue3 + Vite 构建组件库发布到 npm
这篇文章介绍了如何使用Vue3和Vite构建组件库并发布到npm,包括初始化项目、配置项目结构、创建组件目录、设置入口文件以及导出组件等步骤。
1330 0
Vue3 + Vite 构建组件库发布到 npm
|
JavaScript 前端开发 搜索推荐
Nuxt4.0初体验:一个简约、精美、现代化的个人站点导航!
这篇文章介绍了作者使用Nuxt 4.0重构个性化站点导航网站的经历,阐述了Nuxt 4.0的新特性和优势,如更清晰的项目结构、更好的TypeScript体验、更快的CLI和开发速度等,并且分享了重构过程中的体验和项目完成效果。同时,作者还对比了Nuxt.js与Next.js两个框架的优劣,表达了自己对Nuxt.js的偏好。
770 0
Nuxt4.0初体验:一个简约、精美、现代化的个人站点导航!
|
存储 JavaScript 中间件
Nuxt3 实战 (一):初始化项目
这篇文章介绍了Nuxt框架的基本信息,包括什么是Nuxt以及Nuxt3的优点。文章还介绍了Nuxt3的一些特点,如服务端渲染和静态站点生成、模块化、文件系统路由等。此外,文章还提供了项目安装的步骤和目录结构。最后,文章提到了下一步计划,即配置 Eslint、Prettier、Husky、lint-staged、commitlit项目提交规范的过程。
645 3
Nuxt3 实战 (一):初始化项目
Nuxt3 实战 (八):优雅的实现暗黑主题模式
这篇文章介绍了在Nuxt3中实现暗黑模式的过程。首先推荐使用color-mode库来轻易实现暗黑模式切换,并通过pnpm命令安装@nuxtjs/color-mode依赖。然后在nuxt.config.ts配置文件中注入依赖,并根据项目实际情况自定义配置。接着通过toggleDark函数实现切换动画,并在需要的地方加载组件<ColorMode/>,从而达到最终效果。
608 0
Nuxt3 实战 (八):优雅的实现暗黑主题模式
|
前端开发 JavaScript API
TS 中的类型验算,高级通用 API 实现
这篇文章介绍了一些常用的类型通用API封装,包括TS内置类型和关键字的使用,以及TS compiler内部实现的类型。文章截取了一些常用的类型定义和API示例,如Partial、Required、Readonly、NonNullable、Parameters等。还介绍了一些常用的TS关键字,如extends、infer、keyof、typeof、in等。此外,文章还提供了一些实现示例,如Optional API、GetOptional API和UnionToIntersection API。该文章会不断更新。
336 0
TS 中的类型验算,高级通用 API 实现
Next.js 实战 (二):搭建 Layouts 基础排版布局
本文介绍了作者在Next.js v15.x版本发布后,对一个旧项目的重构过程。文章详细说明了项目开发规范配置、UI组件库选择(最终选择了Ant-Design)、以及使用Ant Design的Layout组件实现中后台布局的方法。文末展示了布局的初步效果,并提供了GitHub仓库链接供读者参考学习。
569 1
Next.js 实战 (二):搭建 Layouts 基础排版布局
|
监控 安全 中间件
Next.js 实战 (十):中间件的魅力,打造更快更安全的应用
这篇文章介绍了什么是Next.js中的中间件以及其应用场景。中间件可以用于处理每个传入请求,比如实现日志记录、身份验证、重定向、CORS配置等功能。文章还提供了一个身份验证中间件的示例代码,以及如何使用限流中间件来限制同一IP地址的请求次数。中间件相当于一个构建模块,能够简化HTTP请求的预处理和后处理,提高代码的可维护性,有助于创建快速、安全和用户友好的Web体验。
453 0
Next.js 实战 (十):中间件的魅力,打造更快更安全的应用
|
前端开发 API 开发者
Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画
这篇文章介绍了Framer Motion,一个为React设计的动画库,提供了声明式API处理动画和页面转换,适合创建响应式用户界面。文章包括首屏加载动画、路由加载Loading、路由进场和退场动画等主题,并提供了使用Framer Motion和next.js实现这些动画的示例代码。最后,文章总结了这些效果,并邀请读者探讨更好的实现方案。
487 0
Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画
|
数据采集 搜索推荐 开发者
Nuxt3 实战 (十二):SEO 搜索引擎优化指南
这篇文章介绍了如何为Nuxt.js项目添加favicon图标和TDK(标题、描述、关键词),安装@nuxtjs/seo模块,以及如何设置Robots、Sitemap、OG Image、Schema.org、Experiments等。文章还提到了添加Google Analytics、Microsoft Clarity和Umami统计代码的方法。文章最后总结称,Nuxt.js 3集成了很多SEOModules,使开发者能够更加高效便捷地做好搜索引擎方面的优化。
1180 0
Nuxt3 实战 (十二):SEO 搜索引擎优化指南