基于Sass实现动态css样式切换

文章介绍了如何基于Sass来低成本地实现动态CSS样式切换,通过创建命名空间、定义scss变量和混合指令,实现不同主题的切换。用户可以通过改变HTMLbody的data-theme属性来应用不同的主题样式,从而达到一键换肤的效果。同时,文章提到了在Vue项目中的应用和优化策略,通过vue.config.js配置文件向Sass加载器传递全局变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于Sass低成本实现动态css样式切换

一、基本应用场景

  1. 一键换肤

  2. 关怀模式

二、Sass基础

1. 简介

  • Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库有助于更好地组织管理样式文件,以及更高效地开发项目。

2. 语法

  • 变量
// 变量以美元符号开头,赋值方法与 CSS 属性的写法一样
$width: 5em;
// 直接使用即调用变量
#main {
  width: $width;
}
  • 嵌套规则
// Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器,例如:
#main p {
  width: 97%;
  .redbox {
    color: #000000;
  }
}
// 父选择器 &
.box {
  color: black;
  &-title {
    font-weight: bold;
  }
}
  • 混合指令 @mixin 、引用混合样式 @include

@mixin clearfix {
  display: inline-block;
  &:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
  }
  * html & { height: 1px }
}
.page-title {
  @include clearfix;
  padding: 4px;
}
  • 函数指令@function

$gutter-width: 10px;

@function grid-width($n) {
  @return $n * $grid-width;
}

#sidebar { width: grid-width(5); }

三、实现思路

1. 利用css属性选择器创造命名空间

<!--APP.vue --给APP.vue的body标签添加自定义属性,目的是通过标签选择器将每个主题的样式独立出来,互不影响 -->
<body data-theme="default">
    <div id="app"></div>
    <!-- built files will be auto injected -->
</body>
[data-theme=default] 类名 {
  color: #67C23A;
  font-size: 1.25rem;
  font-weight: 400;
}
[data-theme=new] 类名 {
  color: #F56C6C;
  font-size: 1.75rem;
  font-weight: 600;
}

2. 创建scss变量

// src\assets\style\variable.scss

// 字体颜色
$success: #67C23A !default;
$danger: #F56C6C !default;

// 字体大小 浏览器默认16px
$font-size-base: 1rem !default;
$font-size-md: $font-size-base * 1.25 !default;
$font-size-lg: $font-size-base * 1.75 !default;

// 字重
$font-weight-normal: 400 !default;
$font-weight-bold: 600 !default;

3. 创建theme scssMap对象

// src\assets\theme\index.scss

@import "~@/assets/style/variable.scss";

$themes-Map: (
  // 默认主体
  default: (
    color: $success,
    font-weight: $font-weight-normal,
    font-size: $font-size-md,
  ),
  // new主题
  new: (
    color: $danger,
    font-weight: $font-weight-bold,
    font-size: $font-size-lg,
  ),
);

4. 样式处理scss文件

// src\assets\style\handle.scss

@import "~@/assets/theme/index.scss";

// 定义混合指令--遍历主题map--设置主题样式
@mixin themes-Map {
  @each $theme-name, $theme-value in $themes-Map {
      $theme-map: $theme-value !global;
      // #{} 插值
      [data-theme="#{$theme-name}"] & {
          @content; // slot 引用混合指令时传值
      }
  }
}

// 根据Key获取value的function 
@function getValue($key) {
  @return map-get($theme-map, $key);
}

5. 在页面中使用

<template>
  <div>
    <div class="about">This is an about page</div>
    <div class="btn" @click="themeDefalut">主题1</div>
    <div class="btn" @click="themeNew">主题2</div>
  </div>
</template>
<script>
export default {
  methods: {
    // 点击应用default主题
    themeDefalut() {
      document .getElementsByTagName("body")[0].setAttribute("data-theme", "default");
    },
    // 点击应用new主题
    themeNew() {
      document .getElementsByTagName("body")[0].setAttribute("data-theme", "new");
    },
  }
}
</script>
<style lang="scss" scoped>
@import '@/assets/style/handle.scss'; 
.about {
  @include themes-Map {
    color: getValue('color');
    font-size: getValue('font-size');
    font-weight: getValue('font-weight');
  }
}
</style>

四、优化

// vue.config.js
// 向 webpack 的预处理器 loader 传递选项
// 这样可以向所有 Sass 样式传入共享的全局变量
module.exports = {
  css: {
    loaderOptions: {
      scss: {
        additionalData: `@import "~@/variables.scss";`
      },
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值