跳到主要内容

作用域(Scope)

Less 的一些附加作用域特性

Mixin 作用域特性

直观地说,mixin 可以访问定义作用域。

#ns {
@a: one;
.mixin-1() {
prop: @a;
}
}
.rule {
#ns.mixin-1();
}

/* 输出:
.rule {
prop: one;
}
*/

已弃用的 mixin 作用域特性

这是一个可能在未来版本中被删除的 mixin 作用域特性列表。

#1. (已弃用) Mixin 可以访问调用者作用域。

#ns {
.mixin-1() {
prop: @a;
}
}
.rule {
@a: one;
#ns.mixin-1();
}
/* 输出:
.rule {
prop: one;
}
*/

这是不符合直觉的,因为:

  1. 在大多数其它语言中都不是典型的行为。
  2. 当查看定义时,很难立即知道 mixin 会产生什么输出。

首选方法:将你想要在 mixin 中可见的变量传递给它。

#ns {
.mixin-1(@a) {
prop: @a;
}
}
.rule {
#ns.mixin-1(@a: one);
}

#2. (已弃用) 调用者作用域可以访问 mixin 中的变量

Mixin 将其变量推入调用者作用域,但仅当变量未在本地定义时。

#ns {
.mixin-1() {
@a: one;
@b: two;
}
}
.rule {
@b: three;
#ns.mixin-1();
prop-1: @a;
prop-2: @b;
}
/* 输出:
.rule {
prop-1: one;
prop-2: three;
}
*/

这是不符合直觉的,因为:

  1. 调用者作用域中的变量可以被覆盖。
  2. 这也不是典型的语言行为。
  3. 它与分离的规则集的行为不同。

此外,通过引入 Maps,你可以直接检索变量值(和 mixin)。

首选方法

#ns {
.mixin-1() {
@a: one;
@b: two;
}
}
.rule {
@returns: #ns.mixin-1();
prop-1: @returns[@a];
prop-2: @returns[@b];
}
/* 输出:
.rule {
prop-1: one;
prop-2: two;
}
*/

#3. (已弃用) 调用者作用域可以访问 mixin 中的 mixin

与已弃用的变量行为类似,mixin 也被推入调用者作用域。但是,与变量不同,具有与合并作用域 mixin 相同名称的 mixin 被合并。

#ns {
.mixin-1() {
prop-1: one;
prop-2: two;
}
}
.rule {
#ns();
.mixin-1();
.mixin-1() {
prop-3: three;
}
}
/* 输出:
.rule {
prop-1: one;
prop-2: two;
prop-3: three;
}
*/

首选方法:直接调用 mixin。

#ns {
.mixin-1() {
prop-1: one;
prop-2: two;
}
}
.rule {
.mixin-1() {
prop-3: three;
}
#ns.mixin-1();
.mixin-1();
}

输出:
```less
.rule {
prop-1: one;
prop-2: two;
prop-3: three;
}

小技巧

Credit: less/less.js/issues/1472

这里有一个技巧,可以定义变量并将它们保留在某个私有范围内,防止它们泄漏到全局空间。

& {
// 变量
@height: 100px;
@width: 20px;
// 不要在此范围内定义任何 prop:value(这样做会生成(错误的)输出)。

.test {
height: @height;
width: @width;
}
}

.rest {
height: @height; // 名称错误:变量 @height 未定义
}

在这里,@height@width 仅在由 & { ... } 创建的范围内定义。你还可以在规则内嵌套一个范围:

.some-module {
@height: 200px;
@width: 200px;
text-align: left;
line-height: @height; // 200px

& {
// 覆盖原始值
@height: 100px;
@width: auto;

.some-module__element {
height: @height; // 100px
width: @width; // 200px
}

.some-module__element .text {
line-height: (@height / 2); // 50px
}
}

& {
// 覆盖原始值
@height: 50px;

.some-module__another-element {
height: @height; // 50px
width: @width; // 200px
}

.some-module__another-element .text {
line-height: (@height / 2); // 25px
}
}
}