限制混合值并在提供无效值时抛出异常
Restrict mixin values and throw exception when invalid value is provided
我有以下 Less mixin:
.box-sizing(@value) {
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
并且我只想允许值 'border-box' 和 'content-box' 作为参数,否则 Less 引擎应该抛出异常。我怎样才能做到这一点?因为没有这个验证,我可以向 mixin 写入任何值,它会工作,但它也会生成无效的 CSS,没有人会注意到有错误。
据我所知,没有办法让 Less 编译器针对问题中描述的无效值抛出错误。但是,您可以使用 guards feature.
使 Less 编译器在提供无效值时根本不产生任何输出。
在下面的代码片段中,仅当两个有效值中的任何一个作为输入传递时才会调用 mixin。如果提供不同的值,Less 编译器将找不到匹配项,因此不会输出任何内容。
.box-sizing(@value){
& when (@value=content-box) , (@value=border-box){ /* comma is the or operator */
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
}
#demo{
.box-sizing(content-box);
}
Less 也有一些内置的 type functions 可以与守卫一起使用来检查值是否有效(比如输入是数字还是颜色等)。还有一个 iskeyword
函数,但其中 none 会检查无效的 CSS 值。
如果您有大量有效值,则可以使用如下所示的循环功能。在这里,我们从有效值数组中提取每个值,如果输入值与其中一个匹配,我们就输出属性。如果输入与任何输入值都不匹配,则(再次)不输出任何内容。
@valid-values: content-box, border-box, padding-box;
.box-sizing(@value){
.loop-valid-values(@index) when (@index > 0){
@valid-value: extract(@valid-values, @index);
& when (@value= @valid-value){
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
.loop-valid-values(@index - 1);
}
.loop-valid-values(length(@valid-values));
}
#demo{
.box-sizing(content-box);
}
严格不推荐,但如果您坚持让编译器在提供无效值时抛出一些异常,那么您可能会故意在 无效值部分。
.box-sizing(@value){
& when (@value= content-box), (@value= border-box){
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
& when not (@value= content-box), (@value= border-box){
output: @bwahahaha; /* there is no such variable and hence when the input value is not valid, compiler will complain that variable is undefined */
}
}
#demo{
.box-sizing(conten-box);
}
您可以在另一个名称下隐藏实际的 mixin 实现,并仅为 .box-sizing
:
提供 content-box
/border-box
重载
// impl.:
.box-sizing(border-box) {.box-sizing-impl(border-box)}
.box-sizing(content-box) {.box-sizing-impl(content-box)}
.box-sizing-impl(@value) {
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
// usage:
usage {
.box-sizing(content-box); // OK
.box-sizing(content-foo); // Error: No matching definition was found for `.box-sizing(content-foo)`
}
(与守卫不同,"argument pattern matching"(又名重载)如果不匹配则不会静默跳过)。
以上重复性略低的变体:
.box-sizing(@value) {
.-(@value);
.-(border-box) {.ok}
.-(content-box) {.ok}
.ok() {
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
}
错误消息的描述性较差:No matching definition was found for '.-(content-foo)'
因此您可能会发现使用 .box-sizing_
左右而不是 .-
更好。
-
尽管测试每个 mixin 参数并在不合适时抛出错误的想法有点奇怪。 (你打算为你编写的每个 mixin 都这样做吗?那很无聊......)你最好将一些 CSS validator/lint 放入你的构建链中。
供应商前缀的常用说明:停止为此编写 mixin 并使用 Autoprefixer。
我有以下 Less mixin:
.box-sizing(@value) {
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
并且我只想允许值 'border-box' 和 'content-box' 作为参数,否则 Less 引擎应该抛出异常。我怎样才能做到这一点?因为没有这个验证,我可以向 mixin 写入任何值,它会工作,但它也会生成无效的 CSS,没有人会注意到有错误。
据我所知,没有办法让 Less 编译器针对问题中描述的无效值抛出错误。但是,您可以使用 guards feature.
使 Less 编译器在提供无效值时根本不产生任何输出。在下面的代码片段中,仅当两个有效值中的任何一个作为输入传递时才会调用 mixin。如果提供不同的值,Less 编译器将找不到匹配项,因此不会输出任何内容。
.box-sizing(@value){
& when (@value=content-box) , (@value=border-box){ /* comma is the or operator */
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
}
#demo{
.box-sizing(content-box);
}
Less 也有一些内置的 type functions 可以与守卫一起使用来检查值是否有效(比如输入是数字还是颜色等)。还有一个 iskeyword
函数,但其中 none 会检查无效的 CSS 值。
如果您有大量有效值,则可以使用如下所示的循环功能。在这里,我们从有效值数组中提取每个值,如果输入值与其中一个匹配,我们就输出属性。如果输入与任何输入值都不匹配,则(再次)不输出任何内容。
@valid-values: content-box, border-box, padding-box;
.box-sizing(@value){
.loop-valid-values(@index) when (@index > 0){
@valid-value: extract(@valid-values, @index);
& when (@value= @valid-value){
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
.loop-valid-values(@index - 1);
}
.loop-valid-values(length(@valid-values));
}
#demo{
.box-sizing(content-box);
}
严格不推荐,但如果您坚持让编译器在提供无效值时抛出一些异常,那么您可能会故意在 无效值部分。
.box-sizing(@value){
& when (@value= content-box), (@value= border-box){
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
& when not (@value= content-box), (@value= border-box){
output: @bwahahaha; /* there is no such variable and hence when the input value is not valid, compiler will complain that variable is undefined */
}
}
#demo{
.box-sizing(conten-box);
}
您可以在另一个名称下隐藏实际的 mixin 实现,并仅为 .box-sizing
:
content-box
/border-box
重载
// impl.:
.box-sizing(border-box) {.box-sizing-impl(border-box)}
.box-sizing(content-box) {.box-sizing-impl(content-box)}
.box-sizing-impl(@value) {
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
// usage:
usage {
.box-sizing(content-box); // OK
.box-sizing(content-foo); // Error: No matching definition was found for `.box-sizing(content-foo)`
}
(与守卫不同,"argument pattern matching"(又名重载)如果不匹配则不会静默跳过)。
以上重复性略低的变体:
.box-sizing(@value) {
.-(@value);
.-(border-box) {.ok}
.-(content-box) {.ok}
.ok() {
-webkit-box-sizing: @value;
-moz-box-sizing: @value;
box-sizing: @value;
}
}
错误消息的描述性较差:No matching definition was found for '.-(content-foo)'
因此您可能会发现使用 .box-sizing_
左右而不是 .-
更好。
-
尽管测试每个 mixin 参数并在不合适时抛出错误的想法有点奇怪。 (你打算为你编写的每个 mixin 都这样做吗?那很无聊......)你最好将一些 CSS validator/lint 放入你的构建链中。
供应商前缀的常用说明:停止为此编写 mixin 并使用 Autoprefixer。