使用list-maps将你的Sass技术水平提高到另一层次

简介: Sass3.3版本的出来,你应该开始使用Sass的map功能。多年以来,变量一直是Sass的核心功能。我们使用它越来越让人疲惫,你不乏看到这样写Sass:

Sass3.3版本的出来,你应该开始使用Sass的map功能。

多年以来,变量一直是Sass的核心功能。我们使用它越来越让人疲惫,你不乏看到这样写Sass:

//创建一个核心的颜色

$bravo_gray: #333;

// 将创建的核心颜色分配给一个有语义化的变量

$input-disabled-color:          $bravo_gray;

// 将语义化变量分得更具体化

$input-disabled-background:     lighten($input-disabled-color, 75%);

$input-disabled-border:         lighten($input-disabled-color, 50%);

$input-disabled-text:           lighten($input-disabled-color, 50%);

这样他能很好的运行。我们按约定手动的设置变量。要使用这个功能,我们要这样做:

input[disabled] {

 background-color: $input-disabled-background;

 border-color: $input-disabled-border;

 color: $input-disabled-text;

}

编译出来的CSS:

input[disabled] {

 background-color: #f2f2f2;

 border-color: #b3b3b3;

 color: #b3b3b3;

}

们可以做得更好。在Sass3.3 版本中出一些新的而且非常有趣的功能特性,我们一起来尝试:mapmap在列表中,可以得到很精确定位。Sass的列表功能出来已经很久了,但列表功能表现平平。但是map的出现,使用的层面更为广泛,可以存储在列表中,也可以从列表中检索出值。

libsass缺乏这样的核心功能,但Lu Nelson为此制作了一个附加功能可以使用。

在大多数情况之下,他们使用方法都是大同小异。只是在语法上有一些关键性的差异:每对key:value之间没有冒号(:),而且最后一对key:value之后没有逗号(,)。

下面的示例是使用了Lu Nelson的libsass


使用list-maps

map做的第一个有趣的事情是,你可以在列中存储key:value作为索引值。然后使用$input作为变量命名空间,我们可以按下面的方式操作:

$input: (

 disabled-background lighten($input-disabled-color, 75%),

 disabled-border lighten($input-disabled-color, 50%),

 disabled-text lighten($input-disabled-color, 50%)

);

现在我们将所有的值以keyvalue的形式存储在一个数组中,我们就可以利用Sass的规则开始编写。

在下面的示例中,我使用Sass的map-get()函数从变量$input中检索出它的keymap-get()具有两个参数,像这样:map-get($list,$key)

所以我们不需要使用旧规则:

background-color: $input-disabled-background;

现在我们完全可以这样使用:

background-color: map-get($input, disabled-background);

总之,我们可以像这样更新input[disabled]样式:

input[disabled] {

 background-color: map-get($input, disabled-background);

 border-color: map-get($input, disabled-border);

 color: map-get($input, disabled-text);

}

编译出来的CSS:

input[disabled] {

 background-color: #f2f2f2;

 border-color: #b3b3b3;

 color: #b3b3b3;

}

特别声明:按照上样方法使用,在编译时,命令终端会提示:

DEPRECATION WARNING: Passing lists of pairs to map-get is deprecated and will

be removed in future versions of Sass. Use Sass maps instead. For details, see

http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.

根据map语法说明,我们可以得知,在Sass中,有关于map的语法有两种:


老版本:

$map: (

 key1 value1,

 key2 value2,

 key3 value3

);

新版本

$map:(

 key1:value1,

 key2:value2,

 key3:value3

);

两者区别,就是keyvalue之间添加了冒号(:),像其他语言中使用数组一样。换句话,原文中的示例使用的是老版本语法。我们可以将其更换成新版本的map语法。更换非常简单:

//map老版本语法

$input: (

 disabled-background lighten($input-disabled-color, 75%),

 disabled-border lighten($input-disabled-color, 50%),

 disabled-text lighten($input-disabled-color, 50%)

);

只需要将上面map老版本语法中的keyvalue之间添加冒号即可:

$input: (

 disabled-background: lighten($input-disabled-color, 75%),

 disabled-border: lighten($input-disabled-color, 50%),

 disabled-text: lighten($input-disabled-color, 50%)

);

再次编译,命令终端将不会再报错,而且得到的结果也是一样的:

input[disabled] {

 background-color: #f2f2f2;

 border-color: #b3b3b3;

 color: #b3b3b3;

}

接下来的内容中,译者自动将map的老版本语法按新版本语法书写。


数组中嵌套对象

看代码,还有另一个形式出现。禁用样式是可以重复使用的。使用map可以嵌套这些样式和检索这些值。

可以这样去理解,input元素自身有一个样式,而[disabled]样式相当于input的附属样式,类似于嵌套在input自身样式中。如此一来,这和Sass的map嵌套map功能极其相似。也就是说可以通过map的嵌套来存储和检索出[disabled]的样式。——@大漠

嵌套map工作方式唯一的限制,就是每个键值(key)都要一个值(value)。就像是JSON数据一样,一个值可以设置成另一对key:value。我们来看一个嵌套的map例子:

$variable: (

  key (

      key: value,

      key: value,

      key: (

          key: value,

          key: value

       )

   )

);

看看map嵌套的结构,然后看看我们当前的结构,可以将disabled的空间名重写前面的map

$input: (

 disabled: (

   background: lighten($input-disabled-color, 75%),

   border: lighten($input-disabled-color, 50%),

   text: lighten($input-disabled-color, 50%)

 )

);

如果要使用这个,我们就需要使用map-get-z()函数从键值中检索出需要的值。在下面的示例中,你会看到使用逗号(,)将分隔开:

background-color: map-get-z($input, disabled, background);

整个样式看起来像这样:

input[disabled] {

 background-color: map-get-z($input, disabled, background);

 border-color: map-get-z($input, disabled, border);

 color: map-get-z($input, disabled, text);

}

使用这种方法,编译出来的CSS:

input[disabled] {

 background-color: #f2f2f2;

 border-color: #b3b3b3;

 color: #b3b3b3;

}

特别声明:如果想使用map-get-z()函数功能,需要在你的Sass中添加lunelsonsass-list-maps中的几个函数:

//Sass-list-maps地址:https://github.com/lunelson/sass-list-maps/blob/master/_sass-list-maps.scss

// list-map helper functions

// 0.9.3 -- key() and value() tentatively added as alternatives to 'tuple-' named funcs

// 0.9.6 -- added better error handling; aliased to single version of each

@function tuple-key($tuple) {

 @if length($tuple) < 1 {

   @return null;

 } @else {

   @return nth($tuple, 1);

 }

}

@function tuple-value($tuple) {

 @if length($tuple) < 2 {

   @return null;

 } @else {

   @return nth($tuple, 2);

 }

}

@function key($tuple) {

 @return tuple-key($tuple);

}

@function value($tuple) {

 @return tuple-value($tuple);

}

// 0.9.5 -- added list-map-check()

@function list-map-check($list) {

 @if length($list) == 2 and length(nth($list, 1)) == 1 {

   @return append((), $list, 'comma');

 }

 @return $list;

}

// list-map versions of list-map-get(), -merge() and -remove()

// 0.9.5 -- list-map-check() has been integrated to handle single-pair inputs, and give correct outputs

@function map-get($list, $key, $check: true) {

 @if $check { $list: list-map-check($list); } @each $tuple in $list {

   @if tuple-key($tuple) == $key { @return list-map-check(tuple-value($tuple)); } }

  // @if tuple-key($tuple) == $key { @return list-map-check($tuple); } }

 @return null;

}

// deep/nested map functions: list-map-get-z() and list-map-merge-z()

// 0.9.5 -- list-map-check() has been integrated, implicitly or explicitly

@function map-get-z($list, $keys...) {

 @if $list == null { @return null; }

 $length: length($keys);

 $list: map-get($list, nth($keys, 1));

 @if $length > 1 {

   @for $n from 2 through $length {

     @if $list == null { @return null; }

     $list: map-get($list, nth($keys, $n), false); }

   @return $list; }

 @else { @return $list; }

}

List-maps是智能的

Sass的map还有很多有用的功能,但这里我只说map-has-key()函数,总之如果你的列表中包含了这个key,这将会返回一个布尔值。map-has-key()函数包括两个参数:$listkey。使用@if指令,我们可以像下面这样使用:

@ifmap-has-key($input, disabled) {

 input[disabled] {

   background-color: map-get-z($input, disabled, background);

   border-color: map-get-z($input, disabled, border);

   color: map-get-z($input, disabled, text);

 }

}

在创建自己的框架时,这是非常有帮助的。我们可以根据项目中可见的key做出相应的反应,跟这个非常的类似:

error: unbound variable $input-disabled-background

Sass的map中自带了map-get($map, $key)map-merge($map1, $map2)map-remove($map, $key)map-keys($map)map-values($map)map-has-key($map, $key)keywords($args)函数功能。除此之外,lunelsonlist-maps还自定义了一些有关于map功能的函数,对于我们实际项目中的运用,帮助特别的,感兴趣的同学可以通过git命令(git clone https://github.com/lunelson/sass-list-maps.git)将此库下载到自己的电脑中。——@大漠


结论

总之,在Sass的项目中list-maps是越来越受欢迎的特性。此功能可以帮助我们如何更好的控制项目中的所有变量,以及我们如何更好的应用他们。

相关文章
|
8月前
|
JavaScript 前端开发 测试技术
TypeScript高级类型:探索Mapped Types的威力及衍生
TypeScript高级类型:探索Mapped Types的威力及衍生
|
11月前
|
算法
白话Elasticsearch15-深度探秘搜索技术之使用copy_to定制组合field解决cross-fields搜索弊端
白话Elasticsearch15-深度探秘搜索技术之使用copy_to定制组合field解决cross-fields搜索弊端
54 0
|
11月前
|
JSON JavaScript 数据格式
陪尤雨溪一起,实现 Vuex 无限层级类型推断。(TS 4.1 新特性)
前几天,TypeScript 发布了一项 4.1 版本的新特性,字符串模板类型,还没有了解过的小伙伴可以先去这篇看一下:TypeScript 4.1 新特性:字符串模板类型,Vuex 终于有救了?[1]。 本文就利用这个特性,简单实现下 Vuex 在 modules 嵌套情况下的 dispatch 字符串类型推断,先看下效果,我们有这样结构的 store
|
存储 Java 容器
Map,List的用法与区别,很基础,蛋或许你不通透
Map,List的用法与区别,很基础,蛋或许你不通透
110 0
Map,List的用法与区别,很基础,蛋或许你不通透
|
搜索推荐 API
神兵利器|聚合型空间搜索引擎工具-Search_Viewer
神兵利器|聚合型空间搜索引擎工具-Search_Viewer
150 0
神兵利器|聚合型空间搜索引擎工具-Search_Viewer
|
Web App开发 前端开发 JavaScript
前端工程化探究--source map
本文适合有 webpack 基础的小伙伴进阶学习
前端工程化探究--source map
|
安全 Java API
【Java技术指南】「技术盲点」也许你不了解的Map.merge的用法指南
【Java技术指南】「技术盲点」也许你不了解的Map.merge的用法指南
136 0
改善代码设计 —— 优“.NET技术”化物件之间的特性(Moving Features Between Objects)
  系列博客       1. 改善代码设计 —— 优化函数的构成(Composing Methods)       2. 改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)       3.
925 0
一起谈.NET技术,改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)
  系列博客       1. 改善代码设计 —— 优化函数的构成(Composing Methods)       2. 改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)       3.
675 0