如果你希望 depends 支持复杂逻辑(AND / OR / 嵌套),同时又 兼容你现在的旧格式:
"depends": [
{ "name": "panel_type", "value": "split" },
{ "name": "panel_type", "value": "free_x" }
]
最好的方式是设计一个 简单的逻辑 DSL(条件树)。核心思想:
depends = 逻辑树
支持:
AND
OR
嵌套
"depends": [
{ "name": "panel_type", "value": "split" },
{ "name": "panel_type", "value": "free_x" }
]
解释为:
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 推荐统一:
"depends": {
"or": [
{ "name": "panel_type", "value": "split" },
{ "name": "panel_type", "value": "free_x" }
]
}
可读性最好。
💡 如果你的 FormJson 会越来越复杂(生信分析 UI 很常见),我可以再给你一个 完整的依赖引擎设计,支持:
=
!=
>
<
in
not in
regex
AND
OR
NOT
这样 FormJson 就会变成一个完整的低代码规则系统。