UI库-使用scss处理多主题切换功能

使用scss处理多主题的问题总结,拿来即用,少走弯路

项目当中有类似白天黑夜或者其它主题的切换需求,这类工作最好在项目构建之初便考虑到并且提前配置好,这里结合我在网上查到的一些方法还有实际工作需求,做一个总结.

一 定义主题文件

既然是多主题,就需要我们一开始就需要考虑到提前将UI中的色系及字体等情况做一个统一的配置,如下图,创建一个_themes.scss文件在静态资源目录下,我们一般放在工程中的/src/assets/css下.

$themes: (
  default:(
    /*字体*/
    font-size-lg : 18px,
    /*颜色*/
    bg-color: #fff,
    font-color:#000
  ),
  dark:(
    /*字体*/
    font-size-lg : 36px,
    /*颜色*/
    bg-color: #000,
    font-color:#fff
  )
)

在该文件我们定义两套主题,分别为defaultdark

二 定义主题匹配文件

在实际项目中,通过调用scss函数来匹配不同的主题,创建一个_themeify.scss文件

@import "./_themes.scss";

@mixin themeify {
  @each $theme-name, $theme-map in $themes {
    $theme-map: $theme-map !global;
    [data-theme=#{$theme-name}] & {
      @content;
    }
  }
}

@function themed($key) {
  @return map-get($theme-map, $key);
}

具体scss函数方法使用规则可以参照sass官网,这里用到了预处理中的控制指令,遍历每一项,!global关键词提权到全局.

三 如何使用

1 定义一个其它的scss文件,我们暂且取名为other.scss,使用方法如下:
@mixin home(){
    width: 100px;
    height: 100px;
    @include themeify{
        background-color: themed('bg-color');
        font-size: themed('font-size-lg')
    }
}

这里我们注意到,想要调用配置的主题颜色需要通过@include调用,并通过themed()函数将配置的变量名传入即可.

2 统一导出

创建一个index.scss用于统一的样式导出

@import "./_themeify.scss";
@import "./other.scss";

这样做的目的便于统一管理,结构清晰,此时css文件夹下应该是这几个文件

UI库-使用scss处理多主题切换功能_第1张图片

3 配置全局引入

这里用vite举例,通过下述方式即可

export default defineConfig({
	css:{
        preprocessorOptions:{
          scss:{
            additionalData:'@import "@/assets/css/index.scss";'
          }
        }
  }
})
4 修改当前主题

在vue3工程中,可在根目录下修改index.html给body标签增加data-theme="default"属性

5 使用

vue项目中,可以像下面例子直接使用,无论是正常调用定义的预处理函数,还是直接调用主题颜色都可.

<template>
  <div class="wrapper">
    <div class="box">
      测试文字
    div>
    <div>
      <button @click="changeTheme">切换主题button>
    div>
  div>
template>

<script setup lang="ts">
   import {ref} from "vue";
   //定义主题状态
   let themeType = ref<string>('default');
   /**
    * 改变主题
    */
   const changeTheme = ():void =>{
     themeType.value = themeType.value == 'default'?'dark':'default'
      document.getElementsByTagName('body')[0].setAttribute('data-theme',themeType.value)
   }
script>
<style scoped lang="scss">
 .box{
   @include home();
   @include themeify{
    color: themed('font-color');
   }
 }
style>

示例:

UI库-使用scss处理多主题切换功能_第2张图片

UI库-使用scss处理多主题切换功能_第3张图片

UI库-使用scss处理多主题切换功能_第4张图片

UI库-使用scss处理多主题切换功能_第5张图片

看了不少教程,决定还是好好总结一番,写一篇拿来就能用的文章,让同样碰到该问题的小伙伴能够少走弯路.

你可能感兴趣的:(前端,ui)