vue项目使用scss切换主题


使用 CSS3中var()方式定义

var变量的定义语法 : –变量名 两个短横线加上变量名
var变量的使用 : var(- -变量名)

定义默认样式,可写为

html{
    --body-background:#fff;
}

:root{
    --body-background:#fff;
    --colors:#333;
}

注::root权限要比html高,不存在css的就近原则。

其他样式,写法分为2种:

方法1:

html.dark{
    --body-background:#000;
}

调用方法:

window.document.documentElement.setAttribute('class', "dark")

方法2:

[data-theme="dark"]{
    --body-background:#000;
}

调用方法:

window.document.documentElement.setAttribute('data-theme', "dark")

页面使用:

.menu{
    background-color:var(--body-background);  
    color: var(--colors);    
}

若是自定义--colors,完整代码如下:

<template>
    <div class="menu" :style="styleObj">
        <el-color-picker
            v-model="color"
            :predefine="predefineColors"
            @change="changeColor"
        ></el-color-picker>
    </div>
</template>
<script>
export default {
    data() {
        return {
            color: "#ff4500",
            predefineColors: [
                "#ff4500",
                "#ff8c00",
                "#ffd700",
                "#90ee90",
                "#00ced1",
                "#1e90ff",
                "#c71585",
            ],
            styleObj:{
                "--colors":"#ff4500"
            }
        };
    },
    methods: {
        changeColor(val){
            console.log(val);
            this.styleObj={
                "--colors":val
            }
        }
    },
};
</script>
<style lang="scss">
.menu{
    color: var(--colors);  
}
</style>

使用SCSS中$方式定义

// 新建 themes.scss
$body-background:#fff;
$themes: ( 
    "dark":(
        body-background:$body-background,// 全局背景色,若是这种写法,建议拆分;要么就直接写body-background:#fff;
    ),
    "light":(
        body-background:red,// 全局背景色
    )
);


// 新建 _handle.scss
@import "./themes.scss";
//切换主题时 获取不同的主题色值
@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;
        }
    }
}

//从主题色map中取出对应颜色
@function themed($key) {
    @return map-get($theme-map, $key);
}

//获取背景颜色
@mixin background_color($color) {
    @include themeify {
        background-color: themed($color);
    }
}

vue页面使用

<style lang="scss">
@import "@/assets/css/_handle.scss";

.menu{
    @include background_color("body-background");
}
</style>

不足点:要在 _handle.scss页面里定义每个颜色,若是颜色定义过多,类似background_color函数的定义就很多,而且在页面使用是,不合符css的语法习惯,影响阅读

使用SCSS 在main中引入全局样式

注:此处和在vue.config.js里全局引入的不同

vue.config.js定义全局后,在单页里可以直接写:

<style lang="scss">
.menu{
    background-color:$body-background;
}
</style>

这里只能把所有的样式写在一个文件或是拆分多个文件里,然后在main.js引入,具体如下:

//main.js
import "@/assets/css/global.scss";

global.scss里引入主题,如下:

//global.scss
.theme-dark {
    @import "./theme/dark/index.scss";
}
.theme-light {
    @import "./theme/light/index.scss";
}

新建一个common.scss的页面存放全部样式,或是根据需要拆分,就是说项目的样式不写在单页里

.menu{
    background-color:$body-background;
}
// ...后面省略

在主题scss页面定义颜色:

$body-background:#050505;// 全局背景色
// ...后面省略

// 最后引入
@import "@/assets/css/common.scss";

以下是目录结构

+  |- src
+    |- assets
+       |- css                         // 样式文件夹
+           |- global.scss             // 样式入口
+           |- common.scss             // 全部样式表,可根据功能进行拆分
+               |- theme               // 主题文件夹
+                   |- dark            // 黑色主题文件夹
+                       |- index.scss  // 黑色主题入口文件
+                   |- light           // 浅色主题文件夹
+                       |- index.scss  // 浅色主题入口文件
# ...

不足点:所有的css样式全部和页面功能分开,影响的代码的阅读和修改。


文章作者: 弈心
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 弈心 !
评论
  目录