作用域

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;
}
*/

这是违反直觉的,因为:

  1. 这在大多数其他语言中并不典型。
  2. 在查看定义时,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;
}
*/

这是违反直觉的,因为:

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

此外,随着地图的引入,你可以直接检索变量值(和混合)。

首选方法:

#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;
}
*/

提示与技巧

信用: less/less.js/issues/1472

这里有一个技巧,用于定义变量并将它们保存在一些私有作用域内,以防止它们泄漏到全局空间。

& {
  // 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
    }
  }
}