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

相关文章
|
7月前
|
JavaScript API 开发者
使用 u-navbar 组件实现页面导航和布局的完全指南
使用 u-navbar 组件实现页面导航和布局的完全指南
1525 0
|
JavaScript 容器
Ant Design Vue 中Drawer自定头部的样式、内容部分的样式、弹出层的样式
Ant Design Vue 中Drawer自定头部的样式、内容部分的样式、弹出层的样式
|
5月前
|
开发框架 JavaScript 前端开发
循序渐进BootstrapVue,开发公司门户网站(4)--- 使用b-carousel-slide组件实现图片轮播以及vue-awesome-swiper实现图片滑动展示
循序渐进BootstrapVue,开发公司门户网站(4)--- 使用b-carousel-slide组件实现图片轮播以及vue-awesome-swiper实现图片滑动展示
|
存储 JavaScript 数据安全/隐私保护
js面包屑,如何制作面包屑,什么是面包屑,又如何去理解面包屑是什么呢,对于不会应该怎么办呢?这篇文章告诉你。
js面包屑,如何制作面包屑,什么是面包屑,又如何去理解面包屑是什么呢,对于不会应该怎么办呢?这篇文章告诉你。
185 0
|
7月前
|
JSON JavaScript 数据格式
【经验分享】如何使用scroll-view + swiper制作tabs导航条组件。
【经验分享】如何使用scroll-view + swiper制作tabs导航条组件。
80 6
|
前端开发
css按钮定位在div底部
css按钮定位在div底部
174 0
|
JavaScript
js让滚动条滚到底部
js让滚动条滚到底部
218 0
|
小程序 安全 前端开发
微信小程序自定义导航栏机型适配--底部Tabbar--view高度--底部按钮适配
微信小程序自定义导航栏机型适配--底部Tabbar--view高度--底部按钮适配
936 0
|
JavaScript 容器
ElementUI Dialog 结合Vue实现对话框body“二分”布局
ElementUI Dialog 结合Vue实现对话框body“二分”布局
335 0