简体   繁体   English

LESS:我如何将mixin作为参数传递给另一个mixin?

[英]LESS: How can I pass a mixin as an argument to another mixin?

I have some basic mixins that apply some rules using media queries 我有一些基本的mixin使用媒体查询应用一些规则

.on-small(@rules) {
  @media (@minWidthSmall) { @rules(); }
}

.on-medium(@rules) {
  @media (@minWidthMedium) { @rules(); }
}

// and .on-large, .on-x-large and so on

And I'm trying to build a very simple flex-based grid system, I'm trying to pass the mentioned mixins as parameters so I can have a generic .make-column mixin. 我正在尝试构建一个非常简单的基于flex的网格系统,我正在尝试将提到的mixins作为参数传递,因此我可以使用通用的.make-column mixin。 as follows: 如下:

.make-col(@break-point-mixin, @span, @size) {
  flex: 1;
  box-sizing: border-box;


  /***********************************************************
  Is the following line possible in LESS somehow?
  ***********************************************************/
  @break-point-mixin({
    width: percentage(@span/@size);
    min-width: percentage(@span/@size);
  });
}

.grid-col-on-small(@span: 1, @size: 1) {
  .make-col(@break-point-mixin: .on-small, @span, @size);
}

.grid-col-on-medium(@span: 1, @size: 1) {
  .make-col(@break-point-mixin: .on-medium, @span, @size);
}

But unfortunately passing @break-point-mixin as a parameter and calling it from inside .make-col crashes with: 但遗憾的是,将@break-point-mixin作为参数传递并从内部调用.make-col崩溃:

Unrecognised input. Possibly missing opening '('

No, you can't send a mixin name as a parameter and use it in that way. 不,您不能将mixin名称作为参数发送并以此方式使用它。

Instead you can do something like the below where the media query mixin is called directly from within the wrapper mixin instead of the .make-col mixin. 相反,您可以执行类似下面的操作,直接从包装器mixin而不是.make-col mixin中调用媒体查询mixin。 As the wrapper mixin is aware of the variables that the media query mixin needs this wouldn't result in any problems. 由于包装器mixin知道媒体查询mixin需要的变量,因此不会导致任何问题。

.grid-col-on-small(@span: 1, @size: 1) {
  .make-col(@span, @size);
  .on-small({
    width: percentage(@span / @size);
    min-width: percentage(@span / @size);
  });
}

.grid-col-on-medium(@span: 1, @size: 1) {
  .make-col(@span, @size);
  .on-medium({
    width: percentage(@span / @size);
    min-width: percentage(@span / @size);
  });  
}

If you are concerned about rewriting the rules in the above mixins then you can set them to a ruleset like below and use it. 如果您担心重写上述mixins中的规则,那么您可以将它们设置为如下所示的规则集并使用它。

@colRules: {
             width: percentage(@span / @size);
             min-width: percentage(@span / @size);
           };

.grid-col-on-small(@span: 1, @size: 1) {
  .make-col(@span, @size);
  .on-small(@colRules);
}

.grid-col-on-medium(@span: 1, @size: 1) {
  .make-col(@span, @size);
  .on-medium(@colRules);  
}

Or, you can send the mixin name as a parameter and use guards like below. 或者,您可以将mixin名称作为参数发送,并使用如下所示的警卫。 As we are dealing with break-points here and there shouldn't be lots of them, this approach should help and would probably get my vote. 由于我们在这里处理断点并且不应该有很多断点,这种方法应该有所帮助,并且可能会得到我的投票。

@colRules: {
             width: percentage(@span / @size);
             min-width: percentage(@span / @size);
           };

.make-col(@breakpoint, @span, @size) {
  flex: 1;
  box-sizing: border-box;
  & when (@breakpoint = s) {
    .on-small(@colRules); /* or you could replace this with that mixin's content also */
  }
  & when (@breakpoint = m) {
    .on-medium(@colRules);
  }
  /* and so on for the rest */
}

.grid-col-on-small(@span: 1, @size: 1) {
  .make-col(s, @span, @size);
}

.grid-col-on-medium(@span: 1, @size: 1) {
  .make-col(m, @span, @size);
}

In this particular case (unlike a general case with an arbitrary mixin name) I'd say you're missing the fact that in .on-small / .on-medium these small and medium things are also nothing but parameters and thus should not be a part of the mixin names. 在这种特殊情况下(不像一个任意混入名一般情况下)我会说你错过了一个事实,即在.on-small / .on-medium这些smallmedium东西也没什么,但参数,因此不应成为mixin名称的一部分。 With this in mind your example becomes: 考虑到这一点,您的示例变为:

.on(small, @rules) {
  @media (@minWidthSmall) {@rules();}
}

.on(medium, @rules) {
  @media (@minWidthMedium) {@rules();}
}

.make-col(@device, @span, @size) {
  flex: 1;
  box-sizing: border-box;
  .on(@device, {
    width: percentage(@span/@size);
    min-width: percentage(@span/@size);
  });
}

// usage:

.make-col(small, @span, @size);

Same for your .grid-col-on-* mixins, they are just a single: 您的.grid-col-on-* mixins也是如此,它们只是一个:

.grid-col-on(@device, @span: 1, @size: 1) {
  .make-col(@device, @span, @size);
}

and so on. 等等。

If you really want a flexible/generic grid - never hardcode device/breakpoint names into mixin or variable names (for more rationale and examples see https://github.com/less/less.js/issues/2702 ). 如果你真的想要一个灵活/通用网格 - 永远不要将设备/断点名称硬编码为mixin或变量名称(有关更多基本原理和示例,请参阅https://github.com/less/less.js/issues/2702 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM