Vue implementa el desollado y evita hoyos

  1. archivo _handle.scss:

@import "_themes";
$theme-map: () !global;
@mixin themeify {
  //遍历主题map
  @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
@function themed($key) {
  @return map-get($theme-map, $key);
}

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

//获取字体颜色
@mixin fontColor($color) {
  @include themeify {
      color: themed($color);
  }
}

//获取边框颜色
@mixin borderColor($color) {
  @include themeify {
      border-color: themed($color);
  }
}
//获取边框底部颜色
@mixin borderBtmColor($color) {
  @include themeify {
    border-bottom-color: themed($color);
  }
}

// 获取向下三角形
@mixin borderDownArrow($color){
  @include themeify {
    border-color:  transparent transparent themed($color) themed($color);
  }
}
//遮罩层
@mixin boxShadow($Num,$shadow,$inset:inset) {
  @include themeify {
    box-shadow:$Num themed($shadow) $inset;
    -webkit-box-shadow:$Num themed($shadow) $inset;
  }
}
//2个颜色叠加的遮罩层
@mixin boxShadow2($Num,$shadow,$Num2,$shadow2) { 
  @include themeify {
    box-shadow: $Num themed($shadow),$Num2 themed($shadow2); 
  }
} 

// 获取透明度
@mixin opacityNum($color) {
  @include themeify {
    opacity: themed($color);
  }
}

// 渐变遮罩层
@mixin maskLinearGradient($deg,$color,$per,$from) {
  @include themeify {
      -webkit-mask: linear-gradient($deg,themed($color) $per,$from);
  }
}

// 渐变背景图片
@mixin bImgLinearGradient($drc,$from,$to) {
  @include themeify {
    background-image: -webkit-linear-gradient($drc,themed($from),themed($to));
    background-image: linear-gradient($drc,themed($from),themed($to));
  }
}

//背景图片
@mixin imageThemeURL($path) {
  @each $themename , $theme in $themes {
    [data-theme = '#{$themename}'] & {
      background-image: url($themename +'/'+ $path);
      @content;
    }
  }
}
//重置样式
@mixin resetCss($themename){
  @each $themename , $theme in $themes {
    [data-theme = '#{$themename}'] & {
      @content;
    }
  }
} 
  1. Archivo _themes.scss: las definiciones de color están aquí

$themes:(
  theme_1:(
    bodyBg:#0b1651,
    fontColor: #0de1f6,
    borderColor:#0de1f6
  ),
  theme_2:(
    bodyBg:#000,
    fontColor: #2e85fe,
    borderColor:#2e85fe 
  )
);
  1. Ejemplo de uso:

Importe el archivo "_handle";

<style scoped lang="scss">
    @import "assets/css/themes/_handle";
    body{
        @include backgroundColor('bodyBg');
        @include fontColor('fontColor');
        @include imageThemeURL('img/icon_chart.png');
        @include boxShadow(0 0 10px 2px,'mtopTabConSd');
        @include bImgLinearGradient(to bottom,'sytleSingleMoreOnBgfrom','sytleSingleMoreOnBgto');
        @include boxShadow2(0px 0px 0px 2px,'sytleSingleMoreOnSd1',0px 0px 0px 3px,'borderColor')
    }
</style>
  1. Configuración de App.vue:

let theme=(type)=>{
        const store = useStore();
        store.commit('updateTheme', type);
        document.documentElement.setAttribute( "data-theme", type);
    };
let skinClass=getLocationStorage(GLOBAL_THEME);
  if(skinClass=='undefined'||skinClass==undefined){
    skinClass=store.state.themeType;
  };
//默认颜色
theme(skinClass);

//切换颜色
let changeThemeCk=(skinClass)=>{
    theme(skinClass);
}
  1. Configuración de index.js en el archivo de la tienda:

state() {
    return {
      themeType:'theme_1'
    };
},
mutations:{
/**更新主题 */
    updateTheme(state,type){
      let skinClass=getLocationStorage(GLOBAL_THEME);
      if(skinClass=='undefined'||skinClass==undefined){
        skinClass=state.themeType;
      }else{
        state.themeType=skinClass;
      };
      if(skinClass!==type){
        let themeIndex=type&&type.split('_')[1]||1;
        setLocationStorage(GLOBAL_THEME,type);
        setLocationStorage(GLOBAL_THEME_INDEX,themeIndex);
        window.location.reload()  //手动刷新才能生效
      };
    }
}

archivo de almacenamiento.js:

/*获取*/
export function getLocationStorage(key){
  return window.localStorage.getItem(key);
};

/**保存 */
export function setLocationStorage(key,value){
  return window.localStorage.setItem(key,value);
}

/**删除 */
export function removeLocationStorage(key){
  return window.localStorage.removeItem(key);
}
/**获取对象 */
export function getobjectLocalStorage(key){
  return JSON.parse(window.localStorage.getItem(key));
}

/***保存对象 */
export function setobjectLocalStorage(key, value){
  window.localStorage.setItem(key,JSON.stringify(value));
}
  1. Puntos a tener en cuenta:

El uso de themeify para cambiar la máscara empaquetará todos los estilos de tema correspondientes y el tamaño del archivo será grande, lo que no es muy amigable (si hay muchas máscaras, no se recomienda su uso, el archivo de estilo será muy grande) .

  1. Uso recomendado:

Puede definir diferentes estilos de tema en el componente y luego importar el archivo de tema correspondiente.

Archivo variable.scss: defina el color (hay un color global, puede definir una variable de color global por separado).

$bodyBg:rgba(26,57,150,.34);

archivo index.scss:

@import ‘全局颜色变量’;
@import 'variable';/*当前组件对应颜色变量*/
body{
    background-color:$bodyBg;
}

Importe el archivo de tema correspondiente en el componente xx.vue:

/***导入对应主题样式 */
import(`./${store.state.themeType}/css/index.scss`);

Supongo que te gusta

Origin blog.csdn.net/pinhmin/article/details/128671054
Recomendado
Clasificación