基於Ant Design 和 jQuery UI 的表單設計器
github 地址
概念
- Comonent 組件
- Layout 佈局,一種特殊的Component
- Component Editor 組件屬性編輯器
- Component Factory 組件工廠,創建Component 和 Component Editor
擴展組件
創建一個組件
組件的定義是通過this.props.definition來傳遞的。definition的格式如下:
{
type: 'Checkbox', // 必須存在
title: '多選框', // 必須存在
props:{
'columnNum':2
},
children:[// 只有在Layout 中出現該屬性
componentDefinition,
...
]
}
在this.props 中還提供了renderCounter屬性,每次組件的刷新該屬性值會自增。definition的結構可能是深層次的,然而在Ant Design提供的React 組件中的shouldComponentUpdate(nextProps,nextState)方法的實現是對象的淺層比較,在某些情況下Component Editor對組件屬性的改變不會導致組件的刷新。可以通過renderCounter來解決組件不刷新的問題。
/**
* 組件
*/
@ComponentWrapper
class CheckboxComponent extends Component{
render(){
const { definition :{props}, renderCounter} = this.props;
const defaultValue = props.options.filter(item=>{
return item.checked;
}).map(item=>{
return item.value;
});
return (
<CheckboxGroup options={props.options} value={defaultValue} renderCounter={renderCounter} />
)
}
}
/**
* 組件編輯器
*/
@ComponentEditor
class InputComponentEditor extends PureComponent{
/**
* 當編輯器改變時,此方法被調用
*/
onChange(_, allValues){
if(!isNull(allValues.minLength, allValues.maxLength) && allValues.minLength > allValues.maxLength){
message.warn(`最小長度${allValues.minLength}應該小於最大長度${allValues.maxLength}`);
return false;// 阻止組件的刷新
}
const { definition:{props}, definition } = this.props;
definition.name = getErasure(allValues, 'name');
definition.title = getErasure(allValues, 'title');
Object.assign(props, allValues);
props.minLength = guaranteeNumber(props.minLength, 0, Number.MAX_VALUE);
props.maxLength = guaranteeNumber(props.maxLength, 0, Number.MAX_VALUE);
return true;
}
render(){
return (
<PropsEditor {...this.props} lengthLimit placeholder/>
);
}
}
/**
* 組件工廠
*/
@FactoryRegister(InputComponent,InputComponentEditor)
class InputFactory {
type="Input" // 必須存在
title="單行輸入框" // 必須存在
/**
* 初始化一個組件定義
* @returns {{type: string, title: string}}
*/
createComponentDefinition(){
return {
type: this.type,
title: this.title,
props:{
placeholder: '請輸入'
},
}
}
}
export default InputFactory;
在compoents/index.js 或 layout/index.js 引入自己組件