用sass配置多种主题

594 阅读1分钟
  • 记录一下利用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设计好,提前配好颜色,效率会很高。