Less 4.x 没有内置 each() 函数,所谓“遍历”实为递归 mixin 模拟,依赖 extract()、length() 等基础函数静态展开,直接调用 each() 会报错。

Less 4.x 没有内置 each() 函数——这是常见误解的源头。你看到的“Less each 遍历”实际依赖的是 .each() 混合(mixin)写法,或借助 JavaScript 插件(如 less-plugin-functions),但后者在标准 Less 编译中不生效。
Less 4.x 里根本没有 each() 函数
Less 官方语法中从未提供类似 Sass 的 @each 或 JS 式 each() 内置函数。所有“遍历”效果都靠递归 mixin + 列表解构模拟实现,本质是编译时静态展开,不是运行时循环。
- 尝试直接写
each(@list, { ... })会报错:Unrecognised input - Less 4.0+ 的
for()、range()等函数也不存在——这些是社区插件或旧版 hack - 官方支持的列表操作仅限
extract()、length()、islist()等基础函数
用递归 mixin 模拟遍历生成多类名
这是最稳定、无需插件、兼容所有 Less 4.x 版本的做法。核心思路:定义一个接受列表和索引的 mixin,自身调用自身直到索引越界。
.gen-classes(@list, @i: 1) when (@i =// 调用 .gen-classes(red, green, blue);
编译后会生成:
.class-red { color: #ff6666; }
.class-green { color: #cc9999; }
.class-blue { color: #99cccc; }
- 必须显式控制终止条件(
when (@i =),否则无限递归导致编译卡死 - 变量插值
@{item}只能在选择器、属性值等允许插值的位置使用,不能用于 mixin 名或函数名 - 如果列表项含空格或特殊字符(如
"bg-primary"),需用引号包裹并注意extract()返回带引号字符串,建议加~"..."或用replace()清理
为什么不用 JavaScript 函数插件?
虽然 less-plugin-functions 支持注入 JS 实现的 each(),但它只在 Node.js 环境下通过 less.render() 手动调用时生效,Webpack / Vite / CLI 默认编译流程均不加载插件,且无法在浏览器端 less.js 中使用。
- Webpack 的
less-loader默认不启用插件,需额外配置lessOptions.plugins并确保插件已安装 - 插件返回的 CSS 是字符串拼接结果,丢失源码映射(source map)、变量作用域和类型检查能力
- 一旦项目切换构建工具(比如从 Webpack 换成 Rsbuild),插件逻辑大概率失效
真正容易被忽略的点是:所谓“遍历”在 Less 里永远是编译期静态行为,没有动态响应、没有条件跳过、没有 break/continue。所有逻辑必须能被编译器在展开 mixin 时完全推导出来——这也是为什么递归 mixin 必须用 when 守卫,而不是 if/else。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











