如果你希望 depends 支持复杂逻辑(AND / OR / 嵌套),同时又 兼容你现在的旧格式:
depends
"depends": [ { "name": "panel_type", "value": "split" }, { "name": "panel_type", "value": "free_x" } ]
最好的方式是设计一个 简单的逻辑 DSL(条件树)。核心思想:
depends = 逻辑树
支持:
AND OR 嵌套
解释为:
panel_type = split OR panel_type = free_x
"depends": { "or": [ { "name": "panel_type", "value": "split" }, { "name": "panel_type", "value": "free_x" } ] }
"depends": { "and": [ { "name": "method", "value": "elasticnet" }, { "name": "panel_type", "value": "split" } ] }
"depends": { "and": [ { "or": [ { "name": "panel_type", "value": "split" }, { "name": "panel_type", "value": "free_x" } ] }, { "name": "method", "value": "elasticnet" } ] }
逻辑:
(method = elasticnet) AND (panel_type = split OR panel_type = free_x)
实现一个 条件解析器:
const checkDepends = (depends:any, getFieldValue:any):boolean => { if (!depends) return true // ---------- 旧格式 ---------- if (Array.isArray(depends)) { const group:Record<string,any[]> = {} depends.forEach(d=>{ if(!group[d.name]){ group[d.name] = [] } group[d.name].push(d.value) }) return Object.entries(group).every(([name,values])=>{ return values.includes(getFieldValue(name)) }) } // ---------- OR ---------- if (depends.or) { return depends.or.some((d:any)=> checkDepends(d, getFieldValue) ) } // ---------- AND ---------- if (depends.and) { return depends.and.every((d:any)=> checkDepends(d, getFieldValue) ) } // ---------- 单条件 ---------- if (depends.name) { return getFieldValue(depends.name) === depends.value } return true }
FormJsonComp
替换这里:
const show = it.depends.every( (d:any) => getFieldValue(d.name) === d.value )
为:
const show = checkDepends(it.depends, getFieldValue)
我们需要 找出所有依赖字段:
const extractDependsNames = (depends:any):string[] => { if(!depends) return [] if(Array.isArray(depends)){ return depends.map(d=>d.name) } if(depends.or){ return depends.or.flatMap(extractDependsNames) } if(depends.and){ return depends.and.flatMap(extractDependsNames) } if(depends.name){ return [depends.name] } return [] }
然后:
const dependNames = [...new Set(extractDependsNames(it.depends))]
用于:
shouldUpdate={(prev, cur)=> dependNames.some(name => prev[name] !== cur[name]) }
这样:
只在依赖字段变化时重新 render
现在你的 depends 支持:
{ "or": [ { "name": "A", "value": 1 }, { "name": "B", "value": 2 } ] }
{ "and": [ { "name": "A", "value": 1 }, { "name": "B", "value": 2 } ] }
{ "and": [ { "or": [ { "name": "panel_type", "value": "split" }, { "name": "panel_type", "value": "free_x" } ] }, { "name": "method", "value": "elasticnet" } ] }
[ { "name": "panel_type", "value": "split" }, { "name": "panel_type", "value": "free_x" } ]
以后 JSON 推荐统一:
可读性最好。
💡 如果你的 FormJson 会越来越复杂(生信分析 UI 很常见),我可以再给你一个 完整的依赖引擎设计,支持:
= != > < in not in regex AND OR NOT
这样 FormJson 就会变成一个完整的低代码规则系统。
Github开源生信云平台 DEMO