在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);}
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/486822.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css实现圆周运动效果

在CSS中可以通过 keyframes 动画 和 transform 属性实现元素的圆周运动。以下是一个示例代码&#xff1a; 示例代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content…

Python subprocess.run 使用注意事项,避免出现list index out of range

在执行iOS UI 自动化专项测试的时候&#xff0c;在运行第一遍的时候遇到了这样的错误&#xff1a; 2024-12-04 20:22:27 ERROR conftest pytest_runtest_makereport 106 Test test_open_stream.py::TestOpenStream::test_xxx_open_stream[iPhoneX-xxx-1-250] failed with err…

不一样的CSS(4)--icon图标系列之svg

序言 上一节内容我们讲解了如何利用css去画一个五角星&#xff0c;其中包括了使用svg的方法&#xff0c;有些小伙伴们对svg的使用不是很了解&#xff0c;那么本节内容我们主要来讲一下&#xff0c;关于svg标签的的使用。 目录 序言一、svg的介绍二、安装SVG扩展插件三、SVG基…

springSecurity认证流程

Spring Security 是spring家族中的一个安全管理框架。相比于另一个安全框架Shiro&#xff0c;它提供更丰富的功能和社区资源&#xff0c;但也较难上手。所以一般大项目用spring Security&#xff0c;小项目用Shiro。 一般web应用需要认证和授权&#xff0c;这也是spring Secur…

FastAPI解决跨域报错net::ERR_FAILED 200 (OK)

目录 一、跨域问题的本质 二、FastAPI中的CORS处理 1. 安装FastAPI和CORS中间件 2. 配置CORS中间件 3. 运行FastAPI应用 三、解决跨域报错的步骤 四、案例:解决Vue.js与FastAPI的跨域问题 1. Vue.js前端应用 2. FastAPI后端API 3. 配置CORS中间件 4. 运行和测试 五…

react跳转传参的方法

传参 首先下载命令行 npm react-router-dom 然后引入此代码 前面跳转的是页面 后面传的是你需要传的参数接参 引入此方法 useLocation()&#xff1a;这是 react-router-dom 提供的一个钩子&#xff0c;用于获取当前路由的位置对象location.state&#xff1a;这是从其他页面传…

C++(十二)

前言&#xff1a; 本文将进一步讲解C中&#xff0c;条件判断语句以及它是如何运行的以及内部逻辑。 一&#xff0c;if-else,if-else语句。 在if语句中&#xff0c;只能判断两个条件的变量&#xff0c;若想实现判断两个以上条件的变体&#xff0c;就需要使用if-else,if-else语…

【Keil5教程及技巧】耗时一周精心整理万字全网最全Keil5(MDK-ARM)功能详细介绍【建议收藏-细细品尝】

&#x1f48c; 所属专栏&#xff1a;【单片机开发软件技巧】 &#x1f600; 作  者&#xff1a; 于晓超 &#x1f680; 个人简介&#xff1a;嵌入式工程师&#xff0c;专注嵌入式领域基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大家&#xff1…

三菱CNC数采超详细,资料全备教程,后续更新发那科数采教程

三菱数采详细教程 文章目录 三菱数采详细教程一、介绍1.背景2.需要掌握知识3.需要资料①三菱SDK包&#xff1a;A2②三菱com接口文档③C#代码&#xff1a;④VStudio⑤资料存放网盘 二、程序运行1.调试设备①条件②命令 2.运行软件①打开软件②运行程序 三、数据采集1.代码了解2.…

一文了解模式识别顶会ICPR 2024的研究热点与最新趋势

简介 对模式识别研究领域前沿方向的跟踪是提高科研能力和制定科研战略的关键。本文通过图文并茂的方式介绍了ICPR 2024的研究热点与最新趋势&#xff0c;帮助读者了解和跟踪模式识别的前沿研究方向。本推文的作者是黄星宇&#xff0c;审校为邱雪和许东舟。 一、会议介绍 ICPR…

在 Windows WSL 上部署 Ollama 和大语言模型:从镜像冗余问题看 Docker 最佳实践20241208

&#x1f6e0;️ 在 Windows WSL 上部署 Ollama 和大语言模型&#xff1a;从镜像冗余问题看 Docker 最佳实践 ⭐ 引言 随着大语言模型&#xff08;LLM&#xff09;和人工智能技术的迅猛发展&#xff0c;开发者们越来越多地尝试在本地环境中部署模型进行实验。 但部署过程中常…

混合云策略在安全领域受到青睐

Genetec 发布了《2025 年物理安全状况报告》&#xff0c;该报告根据超过 5,600 名该领域领导者&#xff08;其中包括 100 多名来自澳大利亚和新西兰的领导者&#xff09;的回应&#xff0c;揭示了物理安全运营的趋势。 报告发现&#xff0c;澳大利亚和新西兰的组织采用混合云策…

juc并发编程(下)

一些辅助类 减少计数CountDownLatch 设置一个计数器&#xff0c;通过countDown方法进行减1操作&#xff0c;使用await方法等待计数器不大于0&#xff0c;继续执行await方法之后的语句。 当一个或多个线程调用await方法时&#xff0c;这些线程会阻塞 其他线程调用countDown方…

调用matlab用户自定义的function函数时,有多个输出变量只输出第一个变量

很多朋友在使用matlab时&#xff0c;会使用或自己编辑多个function函数&#xff0c;来满足自己对任务处理的要求&#xff0c;但是在调用function函数时&#xff0c;会出现这个问题&#xff1a;调用matlab用户自定义的function函数时&#xff0c;有多个输出变量只输出第一个变量…

计算机毕设-基于springboot的志愿者招募管理系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

嵌入式蓝桥杯学习7 产生PWM

Cubemx配置 打开cubemx&#xff0c;前面的配置看上文&#xff0c;这里主要配置定时器产生PWM波。 以PA1的TIM2-CH2通道为例进行演示。 1.在Timers中打开TIM2,将Channel2配置为PWM Generation CH2。 2.将Clock Source 选择为Internal Clock。 3.配置Paramater Settings中的参…

LobeChat-46.6k星!顶级AI工具集,一键部署,界面美观易用,ApiSmart 是你肉身体验学习LLM 最好IDEA 工具

LobeChat LobeChat的开源&#xff0c;把AI功能集合到一起&#xff0c;真的太爽了。 我第一次发现LobeChat的时候&#xff0c;就是看到那炫酷的页面&#xff0c;这么强的前端真的是在秀肌肉啊&#xff01; 看下它的官网&#xff0c;整个网站的动效简直闪瞎我&#xff01; GitH…

【分子材料发现】——GAP:催化过程中吸附构型的多模态语言和图学习(数据集处理详解)(二)

Multimodal Language and Graph Learning of Adsorption Configuration in Catalysis https://arxiv.org/abs/2401.07408Paper Data: https://doi.org/10.6084/m9.figshare.27208356.v2 1 Dataset CatBERTa训练的文本字符串输入来源于Open Catalyst 2020 &#xff08;OC20…

[小白系列]Ubuntu安装教程-安装prometheus和Grafana

Docker安装prometheus 拉取镜像 docker pull prom/prometheus 配置文件prometheus.yml 在/data/prometheus/建立prometheus.yml配置文件。&#xff08;/data/prometheus/可根据自己需要调整&#xff09; global:scrape_interval: 15s # By default, scrape targets ev…

oracle之用户的相关操作

&#xff08;1&#xff09;创建用户(sys用户下操作) 简单创建用户如下&#xff1a; CREATE USER username IDENTIFIED BY password; 如果需要自定义更多的信息&#xff0c;如用户使用的表空间等&#xff0c;可以使用如下&#xff1a; CREATE USER mall IDENTIFIED BY 12345…