- 记录一下利用sass配置多种主题的方法~
安装SASS
- 需要以下sass依赖,sass-resources-loader是用来支持全局访问sass变量的
"devDependencies": {
"node-sass": "^4.14.1",
"sass-loader": "^10.1.0",
"sass-resources-loader": "^2.1.1",
},
定义theme-map
- 我在src目录下新建了一个theme文件夹
- _theme.scss文件内容是这样的,我定义了两种风格的主题,一种亮色,一种深色~
//定义theme-map
$lightTheme: (
mainContainerBg: #f3f3f3,
blockBg: $fff,
mainTextColor: #666
);
$darkTheme: (
mainContainerBg: blue,
blockBg: $000,
mainTextColor: #fff
);
$themes: (
light: $lightTheme,
dark: $darkTheme
);
- 可以定义一个variable.scss,里面配置一些基础颜色,然后利用sass颜色函数生成各种颜色~
定义theme方法
- handler_themes.scss文件是酱紫的~
@import './_themes.scss';
@mixin themeify($themes: $themes) {
@each $theme-name, $theme-map in $themes {//$theme-name 主题样式类名, $theme-map样式
//!global 把局部变量强升为全局变量
$theme-map: $theme-map !global;
//判断html的data-theme的属性值 #{}是sass的插值表达式
//& sass嵌套里的父容器标识 @content是混合器插槽,像vue的slot
[data-theme="#{$theme-name}"] & {
@content;
}
}
}
//声明一个根据Key获取颜色的function
@function themed($key) {
@return map-get($theme-map, $key);//从相应主题中拿到相应key对应的值
}
//获取对应主题对应属性下相关状态的属性值
@function isStyle($key) {
//map-get 根据对应的key值返回map中对应的值
@return map-get($theme-map, $key);
};
@mixin styles ($style, $key) {
@include themeify {
#{$style}: isStyle($key);
}
}
//添加 !important
@mixin stylesIm ($style, $key) {
@include themeify {
#{$style}: isStyle($key) !important;
}
}
配置SASS
- 在 vue.config.js中添加~
chainWebpack(config) {
// scss全局参数
const oneOfsMap = config.module.rule('scss').oneOfs.store
oneOfsMap.forEach(item => {
item
.use('sass-resources-loader')
.loader('sass-resources-loader')
.options({
resources: ['./src/theme/handler_themes.scss']
})
.end()
})
}
全局引入
- 在main.js中引入
import './theme/handler_themes.scss'
使用(举个栗子)
- 在body标签或者其他任何你想要添加的页面外层div上加上 data-theme="light" 或者 data-theme="dark"~
<div data-theme="light"></div>
style样式(scss文件)
div {
@include styles('color', 'mainTextColor');
@include themeify {
border: 1px solid themed(elInputBorder);
}
}
okk,完成啦~
- 这种方式配置两种样式,整体写下来还是比较麻烦的,要配置的变量太多了。如果有UI设计好,提前配好颜色,效率会很高。