前端主题切换解决方案
使用sass切换主题

使用sass切换主题,也就是一键换肤的功能,记录一下功能代码
就是给html根标签设置一个data-theme属性,然后通过js切换data-theme的属性值,scss根据此属性来判断使用对应主题变量。这里可以选择持久化vux或接口来保存用户选择的主题。
安装sass
npm install node-sass sass-loader --save-dev
配置sass(如果需要)
vite.config.ts
typescript
export default defineConfig({
css: {
//css预处理
preprocessorOptions: {
scss: {
///引入var.scss全局预定义变量
additionalData: '@import "./src/assets/styles/global.scss";',
},
},
},
});切换主题至少需要用到两个文件
assets/styles/_handle.scss 和 assets/styles/_themes.scss
_themes.scss
在 _themes.scss 中定义你的主题样式,可以多个
scss
$themes: (
//主题1 默认
Azur:
(
//文字主色和副色
font-main-color: #555,
font-secondary-color: #a0a0a0,
font-hover-color: rgb(126, 204, 230),
//导航主色和hover
menu-font-color: #a0a0a0,
menu-font-hover-color: #555,
//导航背景
menu-background: rgba(255, 255, 255, 0.8),
//主色
bg-main-color: rgb(176, 223, 238),
bg-secondary-color: rgba(176, 223, 238,.5),
//主内容背景色
main-bg-color: #fff,
main-border-color: rgb(228, 228, 228),
//滚动条
scrollbar-bg-color: rgba(176, 223, 238, 0),
scrollbar-border-color: rgba(176, 222, 238, 1),
scrollbar-hover-color: rgb(126, 204, 230),
),
//主题2 黑
Dark:
(
//文字
font-main-color: rgb(224, 224, 224),//主色
font-secondary-color: #a0a0a0,//副色
font-hover-color: rgb(255, 255, 255),//hover
//导航
menu-font-color: #a0a0a0,//主色
menu-font-hover-color: #555,//hover
menu-background: rgba(0, 0, 0, 0.8),//背景
//背景色
bg-main-color: rgba(0, 0, 0, 0.253),//主色
bg-secondary-color: rgba(176, 223, 238,.5),//副色
//BODY背景色滤镜
body-color: rgba(0, 0, 0, 0.4),
//主内容
main-bg-color: rgba(0, 0, 0,.8),//背景色
main-border-color: rgba(228, 228, 228,.4),//边框色
//滚动条
scrollbar-bg-color: rgba(0, 0, 0, 0.322),
scrollbar-border-color: rgba(0, 0, 0, 0.8),
scrollbar-hover-color: rgb(0, 0, 0, 0.5)
)
);_handle.scss
_handle.scss使用sass的map遍历、函数、map存取、混合器等相关知识
详细参考官方API文档
scss
//引入你的主题
@import "@/assets/styles/_themes.scss";
//此处用了sass的map遍历、函数、map存取、混合器等相关知识,
//遍历主题map
@mixin themeify {
@each $theme-name, $theme-map in $themes {
//!global 把局部变量强升为全局变量
$theme-map: $theme-map !global;
//这步是判断html的data-theme的属性值 #{}是sass的插值表达式
//& sass嵌套里的父容器标识 @content是混合器插槽,像vue的slot
[data-theme="#{$theme-name}"] & {
@content;
}
}
}
//声明一个根据Key获取颜色的function 从主题色map中取出对应颜色
@function themed($key) {
@return map-get($theme-map, $key);
}
//常用的开发场景下面三种背景颜色、字体颜色、边框颜色 还有其他可以自定义添加,比如阴影..
//获取背景颜色
@mixin background_color($color) {
@include themeify {
background-color: themed($color);
}
}
//获取字体颜色
@mixin font_color($color) {
@include themeify {
color: themed($color);
}
}
//获取边框颜色
@mixin border_color($color) {
@include themeify {
border-color: themed($color);
}
}项目中使用
html
<style lang="scss" scoped>
// 导入handle文件
@import "@/assets/styles/handle";
//使用@include即可
nav {
@include background_color("menu-background");
@include font_color("menu-font-color");
box-shadow: 0 5px 6px -5px rgb(133 133 133 / 60%);
</style>