这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天
引言
在制作网页,特别是展示类型,静态网页等,特别需要主题化功能。 常见的主题化是亮色/暗色的主题切换。就像下面的例子。

需求
如果我们有以下需求,我们需要怎么做呢?
- 闪烁场景问题
- 主题切换
- 记忆主题
- 多种颜色
- 多进程场景的主题同步
抽离颜色
我们实际开发中,会发现,我们需要将所有有关颜色修改,才能完成一次主题切换。但是,我们的主题化功能,对DOM结构却没有改变。那么,为了方便一次性切换,我们有必要将颜色统一抽离出来。同时,我们可以使用CSS变量。如果有多套变量,那么切换主题,就是切换变量,岂不轻而易举。
我们先把所有用到的颜色全部放在一个css文件夹里。
// assets/css/main.css
:root {
--primary-color: #316c72;
--dark-bg: #18181c;
--link: #007fff;
--jjext-color-brand: #1e80ff;
--jjext-color-brand-light: #e8f3ff;
--jjext-color-nav-title: #86909c;
--jjext-color-nav-popup-bg: #ffffff;
--jjext-color-primary: #1d2129;
--jjext-color-secondary-app: #4e5969;
--jjext-color-thirdly: #86909c;
--jjext-color-hover: #1e80ff;
--jjext-color-hover-thirdly: #86909c;
--jjext-color-dropdown-text: #1e80ff;
--jjext-color-divider: #e5e6eb;
--jjext-color-main-bg: #f4f5f5;
}
然后,我们在nuxt.config.ts里面引入
export default defineNuxtConfig({
css: [
'@unocss/reset/tailwind.css',
'@/assets/css/main.css',
],
})
紧接着,我们需要将这些颜色变量引入unocss,方便unocss使用这些颜色变量。
// unocss.config.ts
export default defineConfig({
theme: {
colors: {
primary: 'var(--primary-color)', // #316c72
dark_bg: 'var(--dark-bg)', // #18181c
link: 'var(--link)', // #007fff
nav_icon_color: 'var(--jjext-color-navbar-icon)',
jj_sec_app: 'var(--jjext-color-secondary-app)', // #4e5969
jj_thirdly: 'var(--jjext-color-thirdly)', // #86909c
jj_primary: 'var(--jjext-color-primary)', // #1d2129
jj_hover_bg: 'var(--jjext-color-hover-bg)', // #e8f3ff
},
},
})
图片主题化处理
我们有些icon,logo,通常不是透明的,或者在部分主题下对比度不高,也需要主题化适配。这种情况下,我们有两种解决方案。
第一种,就是直接使用CSS变量,将图片的路径,放在CSS变量里面。然后,我们在使用的时候,直接使用CSS变量。准备多个图片,然后,根据不同的主题,使用不同的图片。
第二种就是使用svg格式的logo。这样,我们只需要通过给svg设置不同的主题class就能切换logo的颜色样式。
当然,有一些需要经常改动的图片,可以直接在数据库准备两套图片,届时根据前端的主题返回对应的图片即可。
主题切换
我们这里可以使用@nuxtjs/color-mode这个库来快速方便解决我们的主题切换。
安装
yarn add --dev @nuxtjs/color-mode
然后,我们将其添加到nuxt.config.ts里
export default defineNuxtConfig({
modules: ['@nuxtjs/color-mode']
})
这样,我们就拥有了黑白主题切换的功能。
使用
可以通过调用 useColorMode ()或直接在模板中访问 $color Mode 来访问颜色模式助手。此助手具有以下属性:
偏好: 实际选择的颜色模式(可以是system) ,更新它,以改变用户的首选颜色模式
我们创建一个ThemeToggle的组件。
<script setup lang="ts">
const color = useColorMode()
function toggleDark() {
color.preference = color.value === 'dark' ? 'light' : 'dark'
}
</script>
<template>
<button class="!outline-none flex" @click="toggleDark">
<span>切换主题</span>
<div class="dark:i-carbon-moon i-carbon-sun" />
</button>
</template>