Öncelikle Demo
Github Linki
Antd'nin Cascader bileşenini özelleştirerek, nihai efekt aşağıdaki gibidir:

1. Demoyu geri yükle

Her şeyden önce, tüm demo rafını geri yüklememiz gerekiyor ve ardından bu temelde özel genişletme yapabiliriz.

1) Gerekli kitaplığı içe aktarın


import QueryBuilder from 'react-querybuilder';
import { AntDActionElement, AntDDragHandle, AntDNotToggle, AntDValueEditor, AntDValueSelector,
} from '@react-querybuilder/antd';
import './index.css';

2) Özel kontrol nesnesi: controlElements


const controlElements = { addGroupAction: AntDActionElement, addRuleAction: AntDActionElement, cloneGroupAction: AntDActionElement, cloneRuleAction: AntDActionElement, combinatorSelector: AntDValueSelector, fieldSelector: AntDValueSelector, notToggle: AntDNotToggle, operatorSelector: AntDValueSelector, removeGroupAction: AntDActionElement, removeRuleAction: AntDActionElement, valueEditor: AntDValueEditor, dragHandle: AntDDragHandle,
};

3) Bir dizi işleç tanımlayın: işleçler


const operators = [ { name: '=', label: '=' }, { name: '!=', label: '!=' }, { name: '<', label: '<' }, { name: '>', label: '>' }, { name: '<=', label: '<=' }, { name: '>=', label: '>=' }, { name: 'contains', label: 'contains' }, { name: 'beginsWith', label: 'begins with' }, { name: 'endsWith', label: 'ends with' }, { name: 'doesNotContain', label: 'does not contain' }, { name: 'doesNotBeginWith', label: 'does not begin with' }, { name: 'doesNotEndWith', label: 'does not end with' }, { name: 'null', label: 'is null' }, { name: 'notNull', label: 'is not null' }, { name: 'in', label: 'in' }, { name: 'notIn', label: 'not in' }, { name: 'between', label: 'between' }, { name: 'notBetween', label: 'not between' },
];

4) RuleGroups için bir birleştirici dizi tanımlayın: birleştiriciler


const combinators = [  { name: 'and', label: 've },  { name: 'or', label: 'veya' },

];
5) Çevrilebilir metni tanımlayın:
çeviriler
{ fields: { title: "Fields", }, operators: { title: "Operators", }, value: { title: "Value", }, removeRule: { label: "x", title: "Remove rule", }, removeGroup: { label: "x", title: "Remove group", }, addRule: { label: "+Rule", title: "Add rule", }, addGroup: { label: "+Group", title: "Add group", }, combinators: { title: "Combinators", }, notToggle: { label: "Not", title: "Invert this group", }, cloneRule: { label: '⧉', title: 'Clone rule' }, cloneRuleGroup: { label: '⧉', title: 'Clone group' }, dragHandle: { label: '⁞⁞', title: 'Drag handle' }
}

6) Bileşen tarafından oluşturulan çeşitli kontrollere atanacak belirli CSS sınıflarını tanımlayın: controlClassnames


const controlClassnames = { removeGroup: 'bg_grey', removeRule: 'bg_grey', combinators: 'bg_grey',
};
İlgili css stili:.
bg_grey { background-color: #ff7e4e; border-color: #ff7e4e;
}
.bg_grey:hover { background-color: #ff9b75; border-color: #ff9b75;
}
7) Sonunda

export default (props: any) => { const { query, setQuery, variableFields, disabled } = props; return ( <QueryBuilder disabled={disabled} query={query} fields={variableFields} operators={operators} combinators={combinators} translations={translations} controlElements={controlElements} controlClassnames={controlClassnames} onQueryChange={(q) => { setQuery(q) }} /> );
};
Bu noktada demonun temel versiyonunu yapılandırdık.
2. açılır listesini Basamaklı kademeli seçime dönüştürün

1) Varsayılan alan kaynağını kapatın


controlElements yapılandırmasını değiştirin:
// fieldSelector: AntDValueSelector,


 QueryBuilder yapılandırmasını değiştirin:// fields={variableFields}
2) CustomValueEditor özel bileşenini tanıtın
controlElements yapılandırmasını değiştirin:
fieldSelector: CustomValueEditor,
QueryBuilder yapılandırmasını değiştirin: ek alanların tanımlanmasına gerek yoktur
controlElements={controlElements}
3) Özel bileşen
CustomValueEditorimport React, { useEffect, useState } from 'react';
import { ValueEditor } from 'react-querybuilder';

import { Cascader, message } from 'antd';
import client from '../../../utils/request';

const CustomValueEditor: React.FC = (props: any) => { const [options, setOptions] = useState([]); const [cascaderDisabled, setCascaderDisabled] = useState(Boolean);
const list = [] as any; const DFS = (op: any, field: any) => { for (let i = 0; i < op.length; i++) { const localName = op[i].name; const localChildren = op[i].children; list.push(localName);
if (localName === field) { return true; } if (localChildren) { const res = DFS(localChildren, field); if (res) { return true; } else { list.pop(localName); } } } }; function displayRender(label: any) { return label[label.length - 1]; }
useEffect(() => { (async (params = {}) => { let data = await client<any>(`接口请求地址`, { params, }); setOptions(data.data); })(); }, []);
if (props.value != '~' && options.length>0) { DFS(options, props.value); }
if (props && options.length>0) { return ( <div> <Cascader expandTrigger="hover" options={options} displayRender={displayRender} onChange={(value: any) => { const data = value[value.length - 1] props.handleOnChange(data); }} defaultValue={list} value={list} /> </div> ); } DFS(options, props.value); return <ValueEditor {...props} />;
};
export default CustomValueEditor;

Seçeneklerin JSON formatı aşağıdaki gibidir:
{ value: 'zhejiang', label: 'Zhejiang', children: [ { value: 'hangzhou', label: 'Hangzhou', children: [ { value: 'xihu', label: 'West Lake', }, ], }, ], }, { value: 'jiangsu', label: 'Jiangsu', children: [ { value: 'nanjing', label: 'Nanjing', children: [ { value: 'zhonghuamen', label: 'Zhong Hua Men', }, ], }, ], },
⚠️ props.handleOnChange()verileri QueryBuilder'a güncelleyecek
onChange={(value: any) => { const data = value[value.length - 1] props.handleOnChange(data); }}