当前位置: 首页 > news >正文

暗黑模式【闪白】解决方案

一、为什么刷新会“闪白”?

浏览器渲染流程:

  1. 下载 HTML → 2. 首次 Paint → 3. 加载 JS → 4. Vue 挂载 → 5. 读取 localStorage → 6. 设置主题

步骤 2 时JS 还没跑,不知道用户上次选的是 dark,于是按默认白色画了一遍;等步骤 6 完成再整体变暗 → 肉眼看到“闪一下”。

破解思路:在第一次 Paint 前就把主题类名写进 <html>


二、Tailwind 打开暗黑开关

tailwind.config.js

export default {darkMode: 'class',   // 手动控制模式content: ['./index.html','./src/**/*.{vue,ts}'],theme: { extend: {} },plugins: []
}
  • 'class' 表示只有 <html class="dark"> 存在时,dark:bg-gray-900 等样式才生效。
  • 区别于 'media'(跟随系统),适合做“一键切换”。

三、核心步骤

index.html

<head><meta charset="UTF-8" /><title>Dark/Light</title><script>(function () {const stored = localStorage.getItem('theme');          // 用户上次选择const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;if (stored === 'dark' || (!stored && prefersDark)) {document.documentElement.classList.add('dark');} else {document.documentElement.classList.remove('dark');}})();</script>
</head>
<body><div id="app"></div><script type="module" src="/src/main.ts"></script>
</body>

关键点

  • 脚本放 <head>不异步
  • 操作 document.documentElement<html> 元素。

四、matchMedia

window.matchMedia('(prefers-color-scheme: dark)')

  • 只读“系统外观”的 API:返回 true → 用户电脑/手机设的是“深色模式”。
  • 作用:做默认 fallback——当用户第一次进站点、还没手动选过主题时,我们就按系统偏好给他配色,而不是硬编码成白色。

代码里怎么用

const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
// 如果本地没存过主题,就用系统值
if (!stored) theme.value = prefersDark ? 'dark' : 'light';//`localStorage.getItem('theme')` 的返回值

实时同步系统变化

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {if (!localStorage.getItem('theme'))    // 用户没手动选过theme.value = e.matches ? 'dark' : 'light';});
  • 系统切深色 → 网页立即跟切;一旦用户手动点过按钮,就不再受系统影响。

五、切换 + 持久化

src/composables/useTheme.ts

import { ref, watchEffect } from 'vue'type Theme = 'light' | 'dark'export function useTheme() {// 初始值:先读本地,没有再读系统const theme = ref<Theme>((localStorage.getItem('theme') as Theme) ??(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'))// 主题变化 → 实时同步 <html> 与 localStoragewatchEffect(() => {const root = document.documentElementif (theme.value === 'dark') root.classList.add('dark')else root.classList.remove('dark')localStorage.setItem('theme', theme.value)})// 一键反转const toggleTheme = () => (theme.value = theme.value === 'light' ? 'dark' : 'light')return { theme, toggleTheme }
}
  • watchEffect任何地方修改 theme.value 都能立即生效。
  • 纯函数,无组件依赖,可在 setup、pinia、路由守卫里随意调用。

六、组件内使用示例

<script setup lang="ts">
import { useTheme } from '@/composables/useTheme'
const { theme, toggleTheme } = useTheme()
</script><template><button@click="toggleTheme"class="w-10 h-10 rounded-full bg-gray-200 dark:bg-gray-700"><span class="dark:hidden">dark</span><span class="hidden dark:inline">light</span></button>
</template>
  • 无需 v-if,Tailwind 自动处理。

七、执行逻辑

浏览器解析 HTML↓
执行内联脚本(dark 类已就位)↓
首次 Paint → 颜色正确↓
Vue 加载 → 使用同一套主题变量

闪白根源被提前脚本扼杀在渲染前


八、PWA优化功能

PWA = Progressive Web App(渐进式 Web 应用)

  • 通过 manifest.json + Service Worker 实现“像原生 App”的能力:
    • 桌面图标 / 启动屏 / 离线访问 / 推送
  • 与暗黑模式的结合点
    1. 启动屏颜色跟随系统:
    // public/manifest.json
    {"theme_color": "#1f2937",      // 深色值"background_color": "#1f2937","display": "standalone"
    }
    
    1. 双击图标全屏打开,主题仍是上次保存的 localStorage 值,体验一致性更好。
http://www.dtcms.com/a/619013.html

相关文章:

  • Spring Boot + Vue 实现一个在线商城(商品展示、购物车、订单)!从零到一完整项目
  • h5可以制作公司网站吗网站用什么框架做
  • AlmaLinux9.6 部署 MariaDB10.11 和 Zabbix7.0 完整教程
  • 东莞市手机网站建设怎么样自己如何做微信小程序
  • 怎么提升网站收录编程培训班学费一般多少钱
  • Git 在团队中的最佳实践--如何正确使用Git Flow
  • 燕郊做网站的安卓程序开发用什么软件
  • 汽车网站建设需要多少钱做网站后期费用
  • Leetcode 3748. Count Stable Subarrays
  • LeetCode Hot100 缺失的第一个正数
  • skywalking中TID
  • 设计公司展厅装修长沙网站搭建seo
  • 私有化部署的gitlab的push failed问题,使用http远程连接(使用token或用户、密码)
  • 人工智能技术- 语音语言- 01 语音识别与合成
  • 枣庄企业网站推广用什么软件做网站hao
  • 网站类型分析招投标网站开发费用
  • 【C语言预处理器全解析】宏、条件编译、字符串化、拼接
  • 生物信息学核心算法全解析:从序列比对到 AI 预测的技术全景
  • 好的网站设计特点北京网站建设公司兴田德润活动
  • 第七章 构建你的智能体框架
  • flash类网站开发石家庄装修设计公司
  • 企业网站推广属于付费推广吗网站用cms
  • 嵌入式面试题:CAN 与 I2C 核心对比(含优缺点,实操视角)
  • 商河县做网站公司网络营销师资格证有什么用
  • 揭阳市住房和城乡建设局官方网站一天必赚100元的游戏
  • Python 常用库
  • 【 Java八股文面试 | Java集合 】
  • 青岛网站优化公司哪家好建网站 找个人
  • 网站建设售后服务网站推广排名
  • 线程控制块 (TCB) 与线程内核栈的内存布局关系