前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nuxt3 实战 (八):优雅的实现暗黑主题模式

Nuxt3 实战 (八):优雅的实现暗黑主题模式

原创
作者头像
白雾茫茫丶
发布2024-06-11 14:07:43
560
发布2024-06-11 14:07:43
举报
文章被收录于专栏:Nuxt3 实战系列Nuxt3 实战系列

前言

Nuxt3 中要实现暗黑模式,需要用到一个库:color-mode,它可以帮助我们很轻易地实现暗黑模式切换。

具体使用

1、安装 @nuxtjs/color-mode 依赖:

代码语言:bash
复制
 pnpm add @nuxtjs/color-mode -D

2、打开 nuxt.config.ts 配置文件注入依赖:

代码语言:js
复制
 export default defineNuxtConfig({
   modules: ['@nuxtjs/color-mode']
 })

3、 你也可以根据项目实际情况自定义配置,以下是一些默认配置:

代码语言:js
复制
import { defineNuxtConfig } from 'nuxt'

 export default defineNuxtConfig({
   modules: ['@nuxtjs/color-mode'],
   colorMode: {
     preference: 'system', // default value of $colorMode.preference
     fallback: 'light', // fallback value if not system preference found
     hid: 'nuxt-color-mode-script',
     globalName: '__NUXT_COLOR_MODE__',
     componentName: 'ColorScheme',
     classPrefix: '',
     classSuffix: '-mode',
     storageKey: 'nuxt-color-mode'
   }
 })

具体的使用文档:NuxtColorMode

按钮模式

1、在 src/components 中新建 ColorMode/index.vue 文件:

代码语言:html
复制
<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>
    <el-tooltip
      :content="`切换${$colorMode.value === 'dark' ? '白天' : '黑夜'}模式`"
      placement="bottom"
    >
      <el-button
        circle
        text
        @click="toggleDark"
      >
        <Icon
          :name="$colorMode.value === 'dark' ? 'i-heroicons-moon-solid' : 'i-heroicons-sun-solid'"
          class="h-5 w-5"
        />
      </el-button>
    </el-tooltip>
  </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>

2、在需要的地方加载组件:

代码语言:html
复制
<ColorMode />

最终效果

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 具体使用
  • 按钮模式
  • 最终效果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档