Less 的一些额外的作用域特性
混入作用域特性
直观地,mixin 可以访问定义作用域。
#ns {
@a: one;
.mixin-1() {
prop: @a;
}
}
.rule {
#ns.mixin-1();
}
/* OUTPUTS:
.rule {
prop: one;
}
*/
弃用的混入作用域特性
这是可能在未来版本中删除的 mixin 作用域功能列表。
#1.(已弃用)混入可以访问调用者作用域。
#ns {
.mixin-1() {
prop: @a;
}
}
.rule {
@a: one;
#ns.mixin-1();
}
/* OUTPUTS:
.rule {
prop: one;
}
*/
这是违反直觉的,因为:
- 这在大多数其他语言中并不典型。
- 在查看定义时,mixin 将产生什么输出并不是很明显。
首选方法: 传入你希望对 mixin 可见的变量。
#ns {
.mixin-1(@a) {
prop: @a;
}
}
.rule {
#ns.mixin-1(@a: one);
}
#2.(已弃用)调用者作用域可以访问混入中的变量
Mixins 会将它们的变量推送到调用者作用域,但前提是该变量未在本地定义。
#ns {
.mixin-1() {
@a: one;
@b: two;
}
}
.rule {
@b: three;
#ns.mixin-1();
prop-1: @a;
prop-2: @b;
}
/* OUTPUTS:
.rule {
prop-1: one;
prop-2: three;
}
*/
这是违反直觉的,因为:
- 调用者作用域中更高的变量可以被覆盖。
- 这也不是典型的语言行为。
- 它不同于分离规则集的行为。
此外,随着地图的引入,你可以直接检索变量值(和混合)。
首选方法:
#ns {
.mixin-1() {
@a: one;
@b: two;
}
}
.rule {
@returns: #ns.mixin-1();
prop-1: @returns[@a];
prop-2: @returns[@b];
}
/* OUTPUTS:
.rule {
prop-1: one;
prop-2: two;
}
*/
#3.(已弃用)调用者作用域可以从混入访问混入
与弃用的变量行为类似,mixins 也被推入调用者作用域。 然而,与变量不同的是,与合并作用域混入同名的混入被合并。
#ns {
.mixin-1() {
prop-1: one;
prop-2: two;
}
}
.rule {
#ns();
.mixin-1();
.mixin-1() {
prop-3: three;
}
}
/* OUTPUT:
.rule {
prop-1: one;
prop-2: two;
prop-3: three;
}
*/
首选方法: 直接调用 mixins。
#ns {
.mixin-1() {
prop-1: one;
prop-2: two;
}
}
.rule {
.mixin-1() {
prop-3: three;
}
#ns.mixin-1();
.mixin-1();
}
/* OUTPUT:
.rule {
prop-1: one;
prop-2: two;
prop-3: three;
}
*/
提示与技巧
这里有一个技巧,用于定义变量并将它们保存在一些私有作用域内,以防止它们泄漏到全局空间。
& {
// Vars
@height: 100px;
@width: 20px;
// Don't define any prop:value on this scope (as doing so will generate (wrong) output).
.test {
height: @height;
width: @width;
}
}
.rest {
height: @height; // Name error: variable @height is undefined
}
此处,@height 和 @width 仅为 & { ... } 创建的作用域定义。你还可以在规则中嵌套作用域:
.some-module {
@height: 200px;
@width: 200px;
text-align: left;
line-height: @height; // 200px
& {
// Override original values
@height: 100px;
@width: auto;
.some-module__element {
height: @height; // 100px
width: @width; // 200px
}
.some-module__element .text {
line-height: (@height / 2); // 50px
}
}
& {
// Override original values
@height: 50px;
.some-module__another-element {
height: @height; // 50px
width: @width; // 200px
}
.some-module__another-element .text {
line-height: (@height / 2); // 25px
}
}
}