
本文介绍如何使用纯 JavaScript 递归解析形如 ["&&", ["==", "a", "b"], [...]] 的嵌套条件数组,并生成结构匹配的嵌套 <ul><li> HTML 树,适用于动态过滤器 UI 的构建与同步。
本文介绍如何使用纯 javascript 递归解析形如 ["&&", ["==", "a", "b"], [...]] 的嵌套条件数组,并生成结构匹配的嵌套 `
- ` html 树,适用于动态过滤器 ui 的构建与同步。
在构建可编辑的动态查询条件 UI(如 SQL WHERE 子句可视化编辑器)时,常需将扁平化、嵌套式的逻辑表达式数组(例如 ["&&", ["==", "name", "John"], ["&&", ["<", "age", "30"]]])渲染为直观的树形 HTML 列表。核心挑战在于:操作符(如 "&&"、"==")始终位于子数组首位,其余元素为操作数或子条件组,需递归展开并正确嵌套 <ul> 结构。
以下是一个健壮、可读性强的递归解决方案:
const generateHTML = (arr) => { const generateAux = ([op, ...conds]) => { // 基础情况:若 conds 中首个元素不是数组,则为叶节点(如 ["==", "field", "value"]) if (conds.length >= 2 && !Array.isArray(conds[0])) { const [left, right] = conds; return `<li>${left} ${op} ${right}</li>`; } // 递归情况:conds 全为子条件数组(如 ["&&", [...], [...]]),需嵌套 ul return `<li>${op} <ul> ${conds.map(generateAux).join('')} </ul> </li>`; }; return `<ul>${generateAux(arr)}</ul>`; }; // 示例数据 const arr = [ "&&", ["==", "first", "1-1"], ["&&", ["==", "second1", "2-1"], ["==", "second2", "2-2"]] ]; // 渲染到页面 document.body.innerHTML = generateHTML(arr);✅ 关键设计说明:
- 使用数组解构 ([op, ...conds]) 直接分离操作符与剩余条件,语义清晰;
- 通过 Array.isArray(conds[0]) 判断是否进入子层级——这是识别嵌套结构的核心逻辑;
- 叶节点要求 conds.length >= 2 && !Array.isArray(conds[0]),确保安全提取左右操作数(避免越界);
- 所有递归调用均返回完整 <li> 字符串,由 join('') 自动拼接,无需手动管理 DOM 节点,兼顾性能与可维护性。
⚠️ 注意事项:
立即学习“前端免费学习笔记(深入)”;
- 该方案假设输入数组格式严格合规(首项为操作符,后续为合法条件或子数组),生产环境建议添加校验(如 Array.isArray(arr) && arr.length > 0);
- 若需支持双向同步(UI 修改 → 数组更新),应为每个 <li> 添加 data-path 或唯一 id,结合事件委托实现增量解析;
- 避免直接 innerHTML = ... 替换整个 body,推荐挂载至指定容器(如 <div id="filter-tree"></div>),提升安全性与可控性。
此实现轻量、无依赖、易于扩展(如增加 "||"、"!=" 支持或添加删除/新增按钮),是构建条件编辑器前端渲染层的理想起点。



















