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

在vue3里使用scss实现简单的换肤功能

实现的换肤功能:主题色切换、亮色模式和暗黑模式切换、背景图切换

主题色就是网站主色,可以配置到组件库上面;亮色模式又分为两种风格:纯白风格和背景图风格,不需要背景图的话可以删掉这部分逻辑和相关定义;暗黑模式就是黑底白字。

写法仅在vue3里有效,vue2或其他框架自行修改写法

换肤示例

换肤示例

scss文件定义

先在variables.module.scss文件定义并导出初始样式
注意此文件必须以.module.scss结尾

$main-color: #1677ff;// while
$while-bg-color: #fafafa;
$while-first-text: #000000e0;
$while-second-text: #000000a6;
$while-third-text: #00000040;
$while-box-bg-color: rgba(255, 255, 255, 0.6);
//dark
$dark-bg-color: #141414;
$dark-first-text: #ffffffd9;
$dark-second-text: #ffffffa6;
$dark-third-text: #ffffff40;
$dark-box-bg-color: rgba(255, 255, 255, 0.05);:export {MainColor: $main-color;//whileWhileBgColor: $while-bg-color;WhileFirstText: $while-first-text;WhileSecondText: $while-second-text;WhileThirdText: $while-third-text;WhileBoxBgColor: $while-box-bg-color;//darkDarkBgColor: $dark-bg-color;DarkFirstText: $dark-first-text;DarkSecondText: $dark-second-text;DarkThirdText: $dark-third-text;DarkBoxBgColor: $dark-box-bg-color;
}

然后在base.scss里定义不同模式下的css属性
此文件可以随意命名

@import "./variables.module";:root {--main-width: 1280px;// 切换背景图需要的变量--base-background:url('../bgImgs/bgImg_53.jpeg');
}
// 亮色模式下文字颜色变量
html[data-theme='light']:root{--first-lv-text: #{$while-first-text};--second-lv-text: #{$while-second-text};--third-lv-text: #{$while-third-text};--box-bg-color: #{$while-box-bg-color};
}
// 暗色模式下的文字颜色变量
html[data-theme='dark']:root{--first-lv-text: #{$dark-first-text};--second-lv-text: #{$dark-second-text};--third-lv-text:#{$dark-third-text};--box-bg-color: #{$dark-box-bg-color};
}html[data-theme='dark']{div,p,span,a,h1,h2,h3,h4,h5,h6,h7,ul,li,button,i{color: #{$dark-first-text};}
}

然后在mian.scss里引入这两个文件并使用css变量

@import './base.scss';
@import "./variables.module";
body {min-width: var(--main-width);overflow-x: hidden;background: var(--base-background) left top no-repeat;background-size: cover;transition: all 0.3s ease;
}

修改主题方法定义

然后在store里定义需要的方法

先定义下ts类型themeTypes.ts(没有ts的可以忽略)

export interface themeType {mode: themeModebgImg: stringisWhile: booleanisDark: booleanmainColor: string
}
export enum themeMode {light = 'light',dark = 'dark'
}

再定义个修改css变量的工具类

/** 修改css样式* @param {string} property css属性名* @param {string} value 要修改的值*/
export function setCssProperty(property: string, value: string) {document.documentElement.style.setProperty(property, value);
}

然后在theme.ts里定义

因为亮色模式下分为纯白和背景图,所以需要mode + isWhile和isDark来区分是亮色模式还是暗黑模式,不需要背景图的话可以修改这部分逻辑

亮色模式和暗黑模式修改关键代码:window.document.documentElement.setAttribute(‘data-theme’, themeMode.light)

import { computed, reactive, ref } from 'vue'
import { defineStore } from 'pinia'
import { themeMode, type themeType } from './types/themeTypes'
import { setCssProperty } from '@/utils/index'
import variable from '@/assets/styles/variables.module.scss'export const useThemeStore = defineStore('theme', () => {/*** 主题分为两种模式:亮色和暗黑* 亮色下又分为两种风格:纯白色风格 和 背景图风格* 暗黑模式就是纯黑背景模式* 三种风格不可兼容* */const theme = reactive<themeType>({mode: themeMode.light,// 修改为你真实的背景图地址bgImg: new URL('@/assets/bgImgs/bgImg_53.jpeg', import.meta.url).href, // 仅在mode === light时生效isWhile: false, // 仅在mode === light时生效isDark: false,mainColor: variable.MainColor})const setTheme = (mode: themeMode, imgUrl?: string) => {theme.mode = mode// theme.isWhile为true表示使用纯白模式;确保isDark为false,并且移除背景图,背景色修改为纯白if (theme.isWhile && mode === themeMode.light) {theme.isDark = falsewindow.document.documentElement.setAttribute('data-theme', themeMode.light)setCssProperty('--base-background', variable.WhileBgColor)} else if (theme.isDark && mode === themeMode.dark) {// 暗黑模式,确保isWhile为false,并且移除背景图,背景色为纯黑theme.isWhile = falsewindow.document.documentElement.setAttribute('data-theme', themeMode.dark)setCssProperty('--base-background', variable.DarkBgColor)} else {// theme.isWhile和theme.isWhile都为false表示使用背景图,此时mode必须为lighttheme.mode = themeMode.lighttheme.isWhile = falsetheme.isDark = falsetheme.bgImg = imgUrl || theme.bgImgwindow.document.documentElement.setAttribute('data-theme', themeMode.light)setCssProperty('--base-background', `url(${theme.bgImg})`)}// 这里把配置存在了本地,有条件的可以存在后台跟用户绑定用接口加载localStorage.setItem('theme', JSON.stringify(theme))}
//页面加载时使用此方法加载配置的主体const loadTheme = () => {const localTheme = localStorage.getItem('theme')if (theme) {Object.assign(theme, JSON.parse(localTheme as string))setTheme(theme.mode, theme.bgImg)}}return {theme,setTheme,loadTheme}
})

使用

然后在换肤vue文件里使用这些方法,注:template非完整代码,仅示例如何调用

<template>
<!--修改主题色我使用的vue3-colorpicker组件 --><ColorPickeris-widgetpicker-type="chrome"shape="square"v-model:pure-color="theme.mainColor"format="hex"@pureColorChange="setMainColor"/><!--修改为纯白 暗黑模式--><div class="use-style"><span>纯白</span><a-switch v-model:checked="theme.isWhile" @change="themeStore.setTheme(themeMode.light)" /></div><div class="use-style"><span>暗黑</span><a-switch v-model:checked="theme.isDark" @change="themeStore.setTheme(themeMode.dark)" /></div><!--选择皮肤(纯白/暗黑模式下,不能选择)--><div class="img-list"><divv-for="(img, index) in bgImgList":key="index"class="img-item"><img:src="img":alt="'皮肤' + index":style="{ cursor: theme.isWhile || theme.isDark ? 'not-allowed' : 'pointer' }"loading="lazy"@click="useImg(img)"/><CheckCircleFilled v-if="theme.bgImg === img" class="selected-icon" /></div></div>
</template>
<script setup lang="ts">import { reactive, ref, watch } from 'vue';// 把sotre和类型导入进来import { useThemeStore } from '@/stores/theme';import { themeMode } from '@/stores/types/appTypes';import { ColorPicker } from 'vue3-colorpicker';import 'vue3-colorpicker/style.css';import { storeToRefs } from 'pinia';const themeStore = useThemeStore();const { theme } = storeToRefs(themeStore);themeStore.loadTheme();const bgImgList = reactive<string[]>([]);const imgCurrent = ref(1);
// 获取图片列表,我这样写是因为放在了本地,根据你的实际情况修改function getBgImgList() {for (let i = 0; i < 100; i++) {bgImgList.push(new URL(`../../assets/bgImgs/bgImg_${i}.jpeg`, import.meta.url).href);}}onMounted(()=>{getBgImgList();})
// 设置主题色,function setMainColor() {localStorage.setItem('theme', JSON.stringify(theme.value));}function useImg(imgUrl: string) {if (theme.value.isWhile || theme.value.isDark) return;themeStore.setTheme(themeMode.light, imgUrl);}
</script>

如果使用了组件库,别忘了把主题色配置到组件上

 <template><a-config-provider:locale="zhCN":theme="{algorithm: appStore.theme.isDark ? theme.darkAlgorithm : theme.defaultAlgorithm,token: {colorPrimary: appStore.theme.mainColor,},}"><a-app><RouterView /></a-app></a-config-provider>
</template><script setup lang="ts">import zhCN from 'ant-design-vue/es/locale/zh_CN';import {  theme } from 'ant-design-vue';import { useThemeStore } from '@/stores/theme';const themeStore = useThemeStore();
</script>

要在不同模式下修改组件库的样式,可以创建如antDesign.scss文件来修改

// 主题兼容
html[data-theme='light']{.ant-layout-sider{background: rgba(255,255,255,0.4);}.ant-layout-header{background: rgba(255,255,255,0.2);}
}
html[data-theme='dark']{.ant-layout-sider{background: rgba(255,255,255,0.08);}.ant-layout-header{background: rgba(255,255,255,0.05);}
}

需要其他配置可以自行往关键文件里添加

相关文章:

在vue3里使用scss实现简单的换肤功能

实现的换肤功能&#xff1a;主题色切换、亮色模式和暗黑模式切换、背景图切换 主题色就是网站主色&#xff0c;可以配置到组件库上面&#xff1b;亮色模式又分为两种风格&#xff1a;纯白风格和背景图风格&#xff0c;不需要背景图的话可以删掉这部分逻辑和相关定义&#xff1b…...

JavaScript编写css自定义属性

一、自定义属性 是在 CSS 中定义的变量&#xff0c;以 --开头。它们可以存储颜色、尺寸、字体等任何 CSS 值&#xff0c;并且可以在整个文档中重复使用。 :root {--primary-color: #3498db;--font-size: 16px; }body {color: var(--primary-color);font-size: var(--font-siz…...

我们来学webservie - WSDL

WSDL 题记WSDL系列文章 题记 举个例子 酒桌上大领导们谈笑风生&#xff0c;把酒临风,其喜洋洋者矣老张说能签下xx项目&#xff0c;一来证明了集团在行业中的翘楚地位&#xff0c;二来感谢各位领导给予的大力支持接下来的一周&#xff0c;项目经理、业务顾问相继入场&#xff0…...

【Agent】构建智能诗歌创作系统:基于多 Agent 的协同创作实现

在探索大语言模型的创意应用过程中&#xff0c;我们开发了一个基于多 Agent 的智能诗歌创作系统。本文将介绍如何通过多个专业化的 Agent 协同工作&#xff0c;实现根据地点和天气信息自动创作诗歌的功能。 GitHub Code 项目地址 核心架构设计 1. Agent 基类设计 from pydan…...

001 LVGL PC端模拟搭建

01 LVGL模拟器介绍 使用PC端软件模拟LVGL运行&#xff0c;而不需要任何嵌入式硬件 环境搭建&#xff1a;codeblocks-20.03mingw-setup 正常安装流程即可 工程获取&#xff1a;LVGL官网-> github仓库 本地安装包下载资源包 工程模版和软件安装包 补充&#xff1a;…...

AJAX三、XHR,基本使用,查询参数,数据提交,promise的三种状态,封装-简易axios-获取省份列表 / 获取地区列表 / 注册用户,天气预报

一、XMLHttpRequest基本使用 XMLHttpRequest&#xff08;XHR&#xff09;对象用于与服务器交互。 二、XMLHttpRequest-查询参数 语法: 用 & 符号分隔的键/值对列表 三、XMLHttpRequest-数据提交 核心步骤 : 1. 请求头 设置 Content-Type 2. 请求体 携带 符合要求 的数…...

mybatis之数据统计与自定义异常处理

文章目录 需求描述定义实体方式一、mybatisPlus实现方式二、自定义SQL实现简单查询过滤查询 异常处理1、SQL拼写异常 在使用Mybatis或MybatisPlus进行数据统计&#xff0c;在【 SpringBoot的Mybatis-plus实战之基础知识】中对mybatisplus引入有介绍&#xff0c;本次要使用其进…...

qt creator使用taglib读取音频元信息,windows平台vcpkg安装

注意&#xff1a;qt creator用的构建组件是qt 6.2.3 MSVC2019 64bit 安装vcpkg // 我的安装位置C:\vcpkg git clone https://github.com/microsoft/vcpkg.git C:\vcpkg cd C:\vcpkg .\bootstrap-vcpkg.bat// 设置系统环境变量 VCPKG_ROOT C:/vcpkg用vcpkg安装taglib vcpkg …...

设计模式之生成器模式

目录 1.简介 2.结构 3.使用场景 4.实例 5.优缺点 6.与其他模式的关系 7.总结 1.简介 生成器模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许你通过一步一步构建复杂对象&#xff0c;而不是通过一个包含大量参数的构造函数或方法。该…...

python学opencv|读取图像(三)放大和缩小图像

【1】引言 前序已经学习了常规的图像读取操作和图像保存技巧&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像-CSDN博客 python学opencv|读取图像&#xff08;二&#xff09;保存彩色图像-CSDN博客 今天我们更近一步&#xff0c;学习放大和缩小图像的技巧&…...

1 数据库(上):MySQL的概述和安装、SQL简介、IDEA连接数据库使用图形化界面

文章目录 前言一、数据库相关的概念二、MySQL概述1 MySQL的安装和配置2 MySQL登录、退出&#xff08;1&#xff09;mysql -uroot -p1234 或者mysql -uroot -p ---- 登录&#xff08;2&#xff09;exit或者quit ---- 退出 3 远程登录服务器上的MySQL命令mysql -hip地址 -P3306 -…...

C++初阶—类与对象(中篇)

第一章&#xff1a;类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&a…...

Leetcode15. 三数之和(HOT100)

链接 一般这种三数之和&#xff0c;四数之和都使用双指针&#xff0c;复杂度最优&#xff0c;次一级可使用哈希表。前者要求有序&#xff0c;后者空间上有花费。 题目&#xff1a; 题目要求答案中不能出现重复vector&#xff0c;比如{-1 1 0}和{-1 0 1}&#xff1b; 这两个…...

Oracle数据库小白备忘

sqlplus相关 导入sql文件 在sqlplus中&#xff0c;导入一个sql文件&#xff0c;是使用或者start。 如当前目录下有一个hello.sql&#xff0c;则可以使用 hello.sql 或者 start hello.sql 来进行导入&#xff0c;功能类似于mysql里面的source。 退出编辑模式 当使用sqlplus…...

DDR4与DDR3服务器内存的关键区别有哪些?

内存作为服务器性能的关键组件之一&#xff0c;已经经历了从DDR3到DDR4的过渡。DDR4内存相较于DDR3在多个方面有所提升&#xff0c;包括速度、带宽、功耗以及数据传输效率等。然而&#xff0c;尽管DDR4内存在性能上占有优势&#xff0c;DDR3内存依然在一些特定场景中得到了广泛…...

Linux: shell: bash: set -x;调试使用

man bash set -x -x After expanding each simple command, for command, case command, select command, or arithmetic for command, display the expanded value of PS4, followed by the command and its expanded arguments or associated word list. 这个可以帮助将变量…...

Hadoop生态圈框架部署 伪集群版(五)- HBase伪分布式部署

文章目录 前言一、Hbase伪分布式部署&#xff08;手动部署&#xff09;1. 下载Hbase2. 上传安装包3. 解压HBase安装包4. 配置HBase配置文件4.1 修改hbase-env.sh配置文件4.2 修改hbase-site.xml配置文件4.3 修改regionservers配置文件4.4 删除hbase中slf4j-reload4j-1.7.33.jar…...

自定义指令,全局,局部,注册

让输入框自动获取焦点(每次刷新自动获取焦点&#xff09; <template><div><h3>自定义指令</h3><input ref"inp" type"text"></div> </template><script> export default {mounted(){this.$refs.inp.focus…...

静坐修心.

文章目录 打坐的历史文化渊源东方的起源与传承西方的接受与演变现代生活中的打坐 盘腿坐对身体的影响促进脊椎健康改善呼吸系统功能增强消化系统机能改善血液循环调节神经系统错误姿势及其他潜在危害 盘腿坐对心理的作用促进内心平静与放松提升自我觉察与内在探索培养专注力与精…...

设计模式c++(一)

文章目录 一、面向对象设计原则二、模版方法三、策略模式四、观察者模式五、装饰模式六、桥模式七、工厂方法_Factory Method八、抽象工厂_Abstract Factory九、原型模式十、构建器_builder十一、单件模式_Singleton十二、享元模式_Flyweight 一、面向对象设计原则 设计模式的…...

Win11系统下MongoDB的安装与配置全攻略

1. MongoDB简介与环境准备 MongoDB作为当前最流行的NoSQL数据库之一&#xff0c;以其灵活的文档存储结构和出色的扩展性深受开发者喜爱。在Win11系统上部署MongoDB&#xff0c;可以轻松搭建本地开发环境或小型生产环境。我最近在帮团队搭建测试环境时&#xff0c;发现很多新手…...

我的世界Java版1.21.4的Fabric模组开发教程(二)创建物品

这是适用于Minecraft Java版1.21.4的Fabric模组开发系列教程专栏第二章——创建物品。想要阅读其他内容&#xff0c;请查看或订阅上面的专栏。 物品(Items) 指的是可以被玩家和其他实体拾起并使用的元素。想要在Minecraft中添加自己的物品&#xff0c;通常需要完成下面的步骤&…...

告别乱码!手把手教你用阿里妈妈数黑体+LVGL 8.3打造炫酷中文界面(附图标字体生成全流程)

告别乱码&#xff01;手把手教你用阿里妈妈数黑体LVGL 8.3打造炫酷中文界面&#xff08;附图标字体生成全流程&#xff09; 在智能家居控制面板、工业HMI等嵌入式设备开发中&#xff0c;中文显示一直是工程师的痛点。传统解决方案要么占用过多Flash空间&#xff0c;要么显示效…...

5个步骤掌握B站推流码获取与OBS直播系统搭建:从入门到专业的完整指南

5个步骤掌握B站推流码获取与OBS直播系统搭建&#xff1a;从入门到专业的完整指南 【免费下载链接】bilibili_live_stream_code 用于在准备直播时获取第三方推流码&#xff0c;以便可以绕开哔哩哔哩直播姬&#xff0c;直接在如OBS等软件中进行直播&#xff0c;软件同时提供定义直…...

Qwen3-Embedding-4B开箱即用:SGlang部署避坑指南

Qwen3-Embedding-4B开箱即用&#xff1a;SGlang部署避坑指南 1. Qwen3-Embedding-4B简介 Qwen3-Embedding-4B是Qwen系列最新推出的文本嵌入模型&#xff0c;专为语义检索、文本分类等任务优化。作为4B参数量的中型模型&#xff0c;它在效果与效率之间取得了良好平衡&#xff…...

低代码拖拽逻辑执行慢10倍?:用3个内存布局优化+1个opcode精简表,让RuleEngine吞吐量突破23,000 TPS

第一章&#xff1a;低代码拖拽逻辑执行慢10倍&#xff1f;&#xff1a;用3个内存布局优化1个opcode精简表&#xff0c;让RuleEngine吞吐量突破23,000 TPS低代码规则引擎在拖拽式策略编排场景下&#xff0c;常因对象频繁分配、字段间接寻址与冗余指令解析导致执行路径膨胀。我们…...

VisualGGPK2:《流放之路》MOD制作的高效解决方案

VisualGGPK2&#xff1a;《流放之路》MOD制作的高效解决方案 【免费下载链接】VisualGGPK2 Library for Content.ggpk of PathOfExile (Rewrite of libggpk) 项目地址: https://gitcode.com/gh_mirrors/vi/VisualGGPK2 你是否曾因复杂的资源提取流程而放弃MOD创作&#…...

一款强大的音视频转字幕工具,完全免费、无广告!

聊一聊有些人你让他上镜&#xff0c;他不习惯。你让他写&#xff0c;他觉得太麻烦。但你让他说&#xff0c;那是头头是道。这个时候&#xff0c;语音输入&#xff0c;语音转文字工具就很实用。今天给大家分享一款&#xff0c;语音输入工具。感觉在使用过程中&#xff0c;有一点…...

MusePublic Art Studio惊艳效果:动态种子演化生成同主题12张连贯艺术组图

MusePublic Art Studio惊艳效果&#xff1a;动态种子演化生成同主题12张连贯艺术组图 1. 引言&#xff1a;当AI成为艺术家的画笔 想象一下&#xff0c;你是一位艺术家&#xff0c;脑海中有一个绝妙的创意主题。你想围绕这个主题创作一个系列作品&#xff0c;比如“赛博朋克森…...

OpenClaw技能扩展:基于nanobot开发自定义自动化模块

OpenClaw技能扩展&#xff1a;基于nanobot开发自定义自动化模块 1. 为什么选择nanobot作为技能开发基础 当我第一次尝试为OpenClaw开发自定义技能时&#xff0c;面对庞大的框架和复杂的依赖关系感到无从下手。直到发现nanobot这个轻量级解决方案&#xff0c;才真正找到了适合…...