作用域(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;
}
*/
这是不符合直觉的,因为:
- 在大多数其它语言中都不是典型的行为。
- 当查看定义时,很难立即知道 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;
}
*/
这是不符合直觉的,因为:
- 调用者作用域中的变量可以被覆盖。
- 这也不是典型的语言行为。
- 它与分离的规则集的行为不同。
此外,通过引入 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
}
}
}