本文记录了 less 中混合的使用。混合之于 less 犹如函数之于 js。它们在很多方面都非常相似,使用less中的混合可以极大的提升代码复用,进而提高维护性和效率。不仅如此还能提升逼格。
less 混合相关的所有知识点如下所示:
1. 普通混合
混合就是代码复用,就像 js 中的函数一样,也接受参数并返回值。就是将样式文件中的相同的代码部分抽取出来,放到一个 class 下面,然后在其它样式作用域中引入。本质上也是 【占位符】 替换,例如:
就可以写成:
如果不使用这种方式的话,就需要在目标元素上加上 className 为 font-hn
,这很不方便。因为能在样式文件中解决的,没有必要放到 jsx 中解决。
2. 混合之后消失
如果不希望 less 编译之后 .font-hn 这个类还存在,那么就在后面加上一对括号 ,这样 h1 和 h2 成功的混合了 .font_hn
但是 .font-hn
本身不会再出现在编译之后的代码中。
编译完成之后的结果为:
3. 带选择器的混合
被混合的部分如果使用到了 &
符号。则编译完成之后 &
表示的是使用混合的选择器而不是定义 &
的选择器。这一点和 js 中的 function 很像,例如:
编译完成后为:
可以认为其计算过程为:
less
.my-hover-minin(){
&:hover {
color: red;
}
}
button {
.my-hover-mixin();
}
// 先混合
button {
&:hover {
color: red;
}
}
// 再编译
button:hover {
color: red;
}
上面的代码中,&
最终指向的是使用混合的 button 选择器。所以,顺序很重要,总是先替换混合,后编译。
4. 带参数的混合
在第 2 节中,加上括号可以使得混合的提供方不被编译。既然是括号了,那么里面当然可以放一些形参,这里的参数指的就是 less 的参数,即以 @
开头的变量。
和 js 中的函数一样,使用参数是为了让代码复用更加灵活。
有一点需要明确,形参必须是以 @
开头的 less 变量,而实参不一定,实参既可以是变量,也可以是常量。
less
@green: green;
.border(@color) {
border: 1px solid @color;
}
h1 {
&:hover {
.border(green);
}
}
h2 {
&:hover {
.border(@green);
}
}
5. 参数的默认值
既然能传参,那就必然能够指定参数的默认值。这和 js 中的函数也是相同的,唯一不同的地方在于,默认参数是使用冒号 :
而不是等号 =
:
less
@green: green;
.border(@color: red) {
border: 1px solid @color;
}
h1 {
&:hover {
.border(green);
}
}
默认值的出现实际上是允许了形参和实参数目的不一致。
6. 混合链
正如 js 中的函数中仍然可以调用其它函数,less 的混合也可做到嵌套:
less
.inner(){
border: 1px solid red;
}
.outer(){
.inner();
color: red;
}
7. 多参数
这里,我还用 js 中的函数做比较。一个函数不可能只能接受一个参数,在 less 中的 mixin 也是如此。因此多参数是基本功能。
不过考虑到 css 中,逗号可能是 css 值组成的一部分 (例如在多张背景图片设置中),因此在 less 中,参数的分隔如果继续沿用逗号,则可能引起歧义;因此在 less 中,分割参数可以使用逗号或者分号。并且推荐使用分号 ;分号出现的时候以分号的分割为准,即分号会让逗号失效。
less
div {
.my-mixin(1,2,3; red, black);
}
上述混合中实际上只传入了两个参数,第一个是 1,2,3
另一个是 red, black
。
而下面只传递了一个参数 1,2,3
:
less
div {
.my-mixin(1,2,3;);
}
值得注意的是,多参数也可以给指定的参数设置默认值。
8. 混合重载
less 中的混合支持重载,即相同的混合名称允许定义不同数目和变量的形参;并且每一个同名函数的内容也可以不同。那么它们之间是如何覆盖的呢?
简单来说,混合重载遵循下面的规则:根据混合使用的时候的传参,在多个重载混合中选出能够正确响应当前传参格式的混合,然后编译这些混合内容,最后再将结果按照优先级选取。
在上面的代码中,定义了同名混合的三个重载,但是在使用的时候只传递了一个参数;这一个参数能满足前两个混合重载的格式,但是不满足第三个重载。因此第三个混合不生效,最终结果是前两个叠加的效果:
9. 命名参数
在 js 函数中,不支持命名参数 ,因为在 js 中都是使用位置传参的。js 实现命名参数的方式是使用一个 object
包裹所有的参数。而在 less 中本身就是支持命名参数的。也就是说除了形参和实参位置对应传递数据之外,还可以使用相同的参数名传递数据。
从上图可以看出,less 甚至支持位置传参和命名传参两种方式混用,遵循:先顺序后命名的规律。
10. argument变量
到这里,可以看出来 less 中的混合和 js 中的函数实际上是非常相似的。它甚至也有 argument
,表示的含义为:所有形参的计算值以空格分割组成的一个字符串,如下所示:
参考 js 中的 argument
变量,在某些情况下剩余参数是非常有用的。并且使用 argument
并不会影响形参的其它使用方式。
11. 匹配模式:less中的switch case
作为命名参数和混合重载的的延伸,使用下面的方式可以实现 less 中的 switch case
:
上图中,在调用重载 .border 的时候,可以传递一个匹配字符作为第一个参数,选出需要的具体混合。在上面的代码中,作为匹配字符的有:all t_l t_r b-L b_r
12. 混合的返回值
既然函数有返回值那么混合也有返回值。但是返回值不用 return
也不用在调用方使用参数接受,主打的是一个默契:
less
.calculate(@w: 16px; @h: 50px) {
@average:((@w+@y)/2);
@sum:(@w+@y);
}
div{
.calculate(16px, 50px);
padding: @average;
margin: @sum;
}
上面是带着 px
计算的,这并没有什么问题。