今天是对sass的一个应用:使用sass切换主题
在开始学习之前,我们先来复习一下相关知识:
使用到的技术
变量:
$bgColor
: 定义了一个全局变量,用于存储背景颜色。$themes
: 使用了 SASS 的映射 (map) 功能,定义了一个包含不同主题样式的对象。$currentTheme
: 定义了一个全局变量,用于存储当前主题。混合指令 (Mixin):
useTheme
: 使用了 SASS 的混合指令功能,定义了一个可复用的 mixin,用于根据当前主题生成 CSS 样式。getVal
: 使用了 SASS 的函数功能,定义了一个函数,用于根据当前主题和参数获取对应的样式值。嵌套:
- 在
useTheme
mixin 中,使用了 SASS 的嵌套功能,将样式规则嵌套在选择器中,避免了重复输入。插值语句:
- 在
useTheme
mixin 和getVal
函数中,使用了 SASS 的插值语句#{}
,用于将变量值插入到字符串中。函数:
map-get
: 使用了 SASS 的映射 (map) 函数,用于获取映射中指定键的值。abs
: 使用了 SASS 的数值函数,用于取绝对值。ceil
: 使用了 SASS 的数值函数,用于向上取整。max
: 使用了 SASS 的数值函数,用于获取最大值。random
: 使用了 SASS 的数值函数,用于生成随机数。其他:
- 使用了
@each
循环遍历映射。- 使用了
@at-root
跳出嵌套。- 使用了
@use
引入其他 SASS 文件。
编写过程
与本文文章绑定的代码文件配套阅读
1. 定义全局变量和样式变量
在scss/theme.scss
文件中,首先定义了两个变量:
$currentTheme
: 这是一个全局变量,用于存储当前主题的键名,初始值为"light"。$theme
: 这是一个映射变量,包含了不同的主题样式,每个主题都有一个键名(如"light"或"dark")和一个映射值,该映射值包含了该主题下的样式属性,如背景色和文字颜色。
2. 定义混合(Mixin)useTheme
useTheme
混合用于遍历$theme
映射,并为每个主题设置特定的样式。它使用@each
指令来遍历$theme
,并为每个主题创建一个html[data-theme='#{$key}']
选择器,其中#{$key}
是主题的键名。在这个选择器内部,使用@content
插槽来插入具体的样式内容。
3. 编写getValue
函数
getValue
函数用于获取当前主题下的特定样式值。它接受一个参数$param
,这是要获取的样式属性的键名。函数内部使用map-get
函数从$theme
映射中获取当前主题的样式值,然后再从该主题的样式值中获取特定的属性值。
4. 使用混合和函数应用主题样式
在.text
类中,使用@include useTheme
来应用主题样式。在@content
插槽中,通过调用getValue
函数来获取color
和background-color
的值,并将它们应用到.text
类的样式上。
5. HTML文件中的主题切换
在index.html
文件中,定义了一个按钮,当点击这个按钮时,会切换html
元素的data-theme
属性值。这个属性值与SCSS文件中的主题键名相对应。JavaScript代码通过改变这个属性来切换主题。
完整的切换主题流程
- 用户点击按钮。
- JavaScript监听到点击事件,并切换
data-theme
属性的值。 - 由于SCSS文件中使用了属性选择器
html[data-theme='#{$key}']
,当data-theme
属性值改变时,对应的主题样式会被应用。 - 由于样式是动态生成的,页面的样式会根据当前的主题变量动态更新。
这样,通过SCSS和JavaScript的结合,就可以实现一个简单的主题切换功能。用户可以通过点击按钮来在"light"和"dark"主题之间切换。
总结
难点在理清编写思路,@mixin的作用是生成dark、light不同主题的标签;getVal函数是获取到属性对应值。明白这两项对理解思路有很好的帮助。
备注:如何配置初始化项目
初始化使用
在vscode中下载插件Live Sass Compiler;
配置Live Sass Compiler:
点击此插件的扩展设置->在setting.json中编辑,将以下代码复制进去
{
"liveSassCompile.settings.formats": [
{
/*
:nested – 嵌套格式
:expanded – 展开格式
:compact – 紧凑格式
:compressed – 压缩格式
*/
"format": "expanded", // 可定制的出口CSS样式(expanded,compact,compressed,nested)
"extensionName": ".css",
"savePath": "~/../css" // 为null 表示当前目录
}
],
/* 排除目录 */
"liveSassCompile.settings.excludeList": [
"/**/node_modules/**",
"/.vscode/**"
],
/* 是否生成对应的map */
"liveSassCompile.settings.generateMap": true,
/* 是否添加兼容前缀 例如:-webkit- -moz- ...等 */
"liveSassCompile.settings.autoprefix": [
"> 1%",
"last 2 versions"
],
"explorer.confirmDelete": false,
}