使用Tailwind CSS在黑暗模式下为你的网站设计样式。
现在,黑暗模式是许多操作系统的第一流功能,为你的网站设计一个黑暗版本以配合默认设计,变得越来越普遍。
为了使这一点尽可能简单,Tailwind包括一个暗色变体,让你在启用暗色模式时以不同的方式设计你的网站:
大家可以看一下,这是vue.js的官网切换主题功能,两个主题(白天/黑夜),通过开关切换换肤。官网是是更换主题后永久更换,刷新后主题也是更换后的。我们可以通过后台存储,将主题类型存储起来,也可以通过浏览器存储,短暂的存储主题类型,以达到主题更换的需求。
根据这个思路我想在我原有的项目上增加一个这个功能,这样项目看起来比较高大上。话不多少,直接开干。
前提
因为我当前的项目是一个前台项目,但是呢 我又不想写css,只能使用tailwindcss
进行样式调整,我是用的技术栈是:vue3+pinia+ts
"pinia": "^2.0.33",
// 持久化
"pinia-plugin-persistedstate": "^3.1.0",
"tailwindcss": "^3.2.7"
安装 Tailwind CSS: npm install tailwindcss --save-dev 或 yarn add tailwindcss。
开始使用之前我们需要搞清楚步骤:
- 监听主题切换
- 根据行为保存当前需要展示的主题 pinia中
- 根据pinia 中保存的当前主题 修改html的class
搞清楚之后 开始整活:
1. 监听主题切换
项目要是有看不懂的css 可以ps
回头我会单独讲解。需要理解的我会给注释。
<template>
<div class="w-[140px] overflow-hidden">
<div
v-for="item in themeArr"
:key="item.id"
@click="onItemClick(item)"
class="flex items-center p-1 cursor-pointer rounded
hover:bg-zinc-100/60 dark:hover:bg-zinc-800"
>
<m-svg-icon
:name="item.icon"
class="w-1.5 h-1.5 mr-1"
fillClass="fill-zinc-900 dark:fill-zinc-300"
></m-svg-icon>
<span class="text-zinc-900 dark:text-zinc-300 text-sm">{{ item.name }}</span>
</div>
</div>
</template>
<script setup>
// 下面的文件将会展示pinia 中的写法
import { storeToRefs } from "pinia"
import appStore from "@/store"
import { computed } from "vue"
const useThemeTypeStore = storeToRefs(appStore.useThemeTypeStore)
// 定义当前主题列表
const themeArr = [
{
id: 0,
type: 'light',
icon: "theme-light",
name: "极简白",
},
{
id: 1,
type: 'dark',
icon: "theme-dark",
name: "极夜黑",
},
{
id: 2,
type: 'system',
icon: "theme-system",
name: "跟随系统",
},
]
const onItemClick = (item) => {
appStore.useThemeTypeStore.changeThemeType(item.type)
}
cons
</script>
2. 根据行为保存当前需要展示的主题 pinia中theme.js
改js只是提供持久化和 选择主题样式,大家可以自己定义相关js。
import { defineStore } from "pinia"
import { ref } from "vue"
const useThemeTypeStore = defineStore("themeType", () => {
const themeType = ref('light')
const changeThemeType = (newTheme: any) => {
themeType.value = newTheme
}
return { themeType, changeThemeType }
},{
// 持久化
persist: [
{
// 存储到sessionStorage
paths: ["themeType"],
storage: sessionStorage,
key:'themeType'
}
],
})
export default useThemeTypeStore
utils/theme.ts
import appStore from "@/store"
import { watch } from "vue"
// 系统监听变量
let matchMedia: any = ""
const watchSystemThemeChange = () => {
// 仅需一次初始化
if (matchMedia) return
// Window 的 matchMedia() 方法返回一个新的 MediaQueryList 对象,表示指定的媒体查询 (en-US)字符串解析后的结果。返回的 MediaQueryList 可被用于判定 Document 是否匹配媒体查询,或者监控一个 document 来判定它匹配了或者停止匹配了此媒体查询。
matchMedia = window.matchMedia("(prefers-color-scheme: dark)")
matchMedia.onchange = () => {
changeTheme('system')
}
}
/**
* 变更主题
* @param theme
*/
const changeTheme = (theme: any) => {
let themeClassName = ""
switch (theme) {
case 'light':
themeClassName = "light"
break
case 'dark':
themeClassName = "dark"
break
case 'system':
// 调用方法监听系统主题变化
watchSystemThemeChange()
themeClassName = matchMedia.matches ? "dark" : "light"
break
}
// 修改 html中class
const html = document.querySelector("html")
if (html) {
html.className = themeClassName
}
}
// 监听pinia 里面定义的 变量
export const useTheme = () => {
watch(
() => appStore.useThemeTypeStore.themeType,
val => {
changeTheme(val)
},
{
immediate: true,
}
)
}
3. 根据pinia 中保存的当前主题 修改html的class
代码详解:
现在,只要HTML树中较早出现dark:{class}类,它们就会被应用,而不是根据prefers-color-scheme来应用。
tailwindcss 内置的 Dark Mode 由两部分组成:
- dark 修饰符,用于指定暗黑模式下的样式
- darkMode 配置,指定暗黑模式的应用标识
使用 dark 修饰符指定样式
<div class="bg-white dark:bg-slate-800 rounded-lg px-6 py-8 ring-1 ring-slate-900/5 shadow-xl">
<div>
<span class="inline-flex items-center justify-center p-2 bg-indigo-500 rounded-md shadow-lg">
<svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"><!-- ... --></svg>
</span>
</div>
<h3 class="text-slate-900 dark:text-white mt-5 text-base font-medium tracking-tight">Writes Upside-Down</h3>
<p class="text-slate-500 dark:text-slate-400 mt-2 text-sm">
The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.
</p>
</div>
tailwindcss 通过 extractor 提取 html 和 js 中的 class,变体 class
.dark:bg-slate-800 作为独立项被提出。 默认情况下, tailwindcss
通过媒体查询自动跟随系统切换暗黑模式。也可以设置 darkMode 改用类策略,手动切换暗黑模式。
需要注意的是 tailwindcss 支持颜色透明度修改器,也就是用 bg-slate-700/50 这样的写法给背景加透明度 background-color: rgb(55 65 81 / 0.5) 。因此色值定义中需要保留 <alpha-value> 占位符供 tailwindcss 实现透明度修改器,同时把 CSS 变量赋值为 rgb 或 hsl 的组成值即可。