封装一个漂亮的ant design form标签组件

在ant design 的form组件中 能用于提交的组件比较少,所以我在这写了一个可以单选、多选标签提交的组件,调用非常简单。

代码:

  1 import React,{Fragment} from 'react';
  2 import { Tag,Icon,Input } from 'antd';
  3 export interface TagDataType{
  4     data:string,
  5     color:string,
  6     key:string
  7 }
  8 export interface Props {
  9     data:Array<TagDataType>,
 10     click?:boolean,//是否可点击
 11     defaultKey?:string | Array<string>,//默认选择tag的key
 12     checkbox?:boolean,//多选
 13     form?:any,//form表单
 14     dataValidationName?:string,//设置提交名称,若用此参数提交则提交选中的data,用于菜单提交获取
 15     keyValidationName?:string,//设置提交名称,若用此参数提交则提交选中的key,用于菜单提交获取
 16     notNull?:boolean,//选项不能为空
 17 }
 18  
 19 export interface State {
 20     keys:string,//选中的标签的key,用','分割
 21     datas:string,//选中的标签的data,用','分割
 22     styleState:number | Array<number>,//选中的下标集
 23 }
 24  
 25 class TagOpt extends React.Component<Props, State> {
 26     constructor(props: Props) {
 27         super(props);
 28         //验证传入数据的合法性
 29         if(this.props.notNull && !!!this.props.defaultKey){
 30             throw Error('TagOpt选中项为空,设置defaultKey!');
 31         }
 32         if(!!this.props.form && !!!this.props.keyValidationName && !!!this.props.dataValidationName){
 33             throw Error('若要使用form提交,请设置keyValidationName或dataValidationName!');
 34         } 
 35         this.state=this.setDefaultVal();      
 36     }
 37     //鼠标点击标签事件
 38     TagClick = (tagData:TagDataType,index:number) =>{
 39         if(this.props.click !== undefined && this.props.click){
 40             if(this.props.checkbox){
 41                 const optIf = this.optIf(index);
 42                 let styleState:Array<number> = new Array();;
 43                 if(typeof this.state.styleState === 'object'){
 44                     styleState = [...this.state.styleState];
 45                 }else{
 46                     styleState = [this.state.styleState];
 47                 }
 48                 if(optIf.state){
 49                     //点击已选择
 50                     //如果设置不为空且选中选项大于1或者没有设置不为空选项
 51                     //则清空
 52                     if(this.props.notNull && styleState.length>1 || !!!this.props.notNull){
 53                         styleState.splice(optIf.index,1);
 54                         this.setState({
 55                             keys:this.moveSubString(this.state.keys,tagData.key),
 56                             datas:this.moveSubString(this.state.datas,tagData.data),
 57                             styleState
 58                         },()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')});
 59                     } 
 60                 }else{
 61                     //点击未选择
 62                     styleState.splice(styleState.length,0,index);
 63                     this.setState({
 64                         keys:this.addSubString(this.state.keys,tagData.key),
 65                         datas:this.addSubString(this.state.datas,tagData.data),
 66                         styleState
 67                     },()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')});
 68                 }
 69             }else{
 70                 if(this.state.styleState === index){
 71                     //点击已选择
 72                     //若设置可以为空
 73                     //则清空
 74                     if(!!!this.props.notNull){
 75                         this.setState({keys:'',datas:'',styleState:this.props.data.length}
 76                         ,()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')});
 77                     }
 78                 }else{
 79                     //点击未选择
 80                     this.setState({keys:tagData.key,datas:tagData.data,styleState:index}
 81                     ,()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')});
 82                 }
 83             } 
 84         }   
 85     }
 86     //返回移出指定子串的字符串,移出所有重复子串
 87     moveSubString = (str:string,subString:string):string => {
 88         let array:Array<string> = str.split(',');
 89         for(let i=0;i<array.length;i++){
 90             if(array[i] === subString){
 91                 array.splice(i,1);
 92             }
 93         }
 94         return array.toString();
 95     }
 96     //返回增加子串的字符串,重复则不增加
 97     addSubString = (str:string,subString:string|Array<string>) =>{
 98         if(typeof subString === 'string'){
 99             let comma = str !==''?',':'';
100             return str +comma+subString;
101         }else{
102             let s:string = str;
103             for(let i=0;i<subString.length;i++){
104                 let comma = s !==''?',':'';
105                 s+=comma+subString[i];
106             }
107             return s;
108         }
109     }
110     //选择判断
111     optIf = (index:number):{state:boolean,index:number} => {
112         if(typeof this.state.styleState ==='number'){
113             return {state:this.state.styleState === index,index:0};
114         }else{
115             let falg:boolean = false;
116             const styleState = this.state.styleState;
117             let i=0;
118             for(;i<styleState.length;i++){
119                 if(styleState[i] === index){
120                     falg = true;
121                     break;
122                 }
123             }
124             return {state:falg,index:i};
125         }
126     }
127     //写入表单
128     setVal = (data:string,type:string) => {
129         if(this.props.form != undefined){
130             let json:object = {}
131             if(type === 'data'){
132                 if(this.props.dataValidationName !== undefined){
133                     json[this.props.dataValidationName] = data;
134                     this.props.form.setFieldsValue(json);
135                 }
136             }else if(type === 'key'){
137                 if(this.props.keyValidationName !== undefined){
138                     json[this.props.keyValidationName] = data;
139                     this.props.form.setFieldsValue(json);
140                 }
141             }
142         }
143     }
144     //默认值转换
145     setDefaultVal=():State=>{
146         if(this.props.checkbox){
147             //多选框,值为1个或数组
148             let styleState:Array<number> = new Array();
149             let keys:Array<string> = new Array();
150             let datas:Array<string> = new Array();
151             const {defaultKey,data} = this.props;
152             if(typeof defaultKey === 'object'){
153                 for(let i=0;i<defaultKey.length;i++){
154                     for(let j=0;j<data.length;j++){
155                         if(defaultKey[i] === data[j].key){
156                             styleState.push(i);
157                             keys.push(data[j].key);
158                             datas.push(data[j].data);
159                         }
160                     }
161                 }
162                 return {
163                     keys:this.addSubString('',keys),
164                     datas:this.addSubString('',datas),
165                     styleState 
166                 }
167             }else{
168                 let i:number = 0;
169                 let key:string = '';
170                 let dat:string = '';
171                 for(;i<data.length;i++){
172                     if(data[i].key === defaultKey){
173                         key=data[i].key;
174                         dat=data[i].data;
175                         break;
176                     }
177                 }
178                 return { keys:key,datas:dat,styleState: i };
179             }  
180         }else if(this.props.checkbox === undefined && typeof this.props.defaultKey ==='string' ||
181             !this.props.checkbox && typeof this.props.defaultKey ==='string'){
182             //多选未设置且默认值为1个或单选且默认值为一个
183             let i:number = 0;
184             let key:string = '';
185             let dat:string = '';
186             if(this.props.defaultKey !== undefined){
187                 const data = this.props.data;
188                 for(;i<data.length;i++){
189                     if(data[i].key === this.props.defaultKey){
190                         key=data[i].key;
191                         dat=data[i].data;
192                         break;
193                     }
194                 }
195             }
196             return { keys:key,datas:dat,styleState: i };
197         }else if(this.props.defaultKey === undefined || this.props.defaultKey === '' || this.props.defaultKey === []){
198             if(this.props.checkbox){
199                 return { keys:'',datas:'',styleState: [] };
200             }else{
201                 return { keys:'',datas:'',styleState: this.props.data.length };
202             }
203         }else{
204             return {keys:'',datas:'',styleState: this.props.data.length};
205         }
206     }
207     render() {
208         const content:any = this.props.data.map((tagData:TagDataType,index:number)=>{
209             const cursor:any = this.props.click !== undefined && this.props.click ?'pointer':'default';
210             return(
211                 <Tag color={tagData.color} key={tagData.key} onClick={this.TagClick.bind(this,tagData,index)} style={{cursor}}>
212                     {tagData.data}
213                     {this.optIf(index).state?<Icon type="check" />:undefined}
214                 </Tag>
215             )
216         });
217         return ( 
218             <Fragment>
219                 {content}
220                 {
221                     !!this.props.click && !!this.props.form && !!this.props.form.getFieldDecorator && !!this.props.keyValidationName?
222                     this.props.form.getFieldDecorator(this.props.keyValidationName, {
223                         initialValue:this.state.keys,
224                     })(<Input type="hidden"/>)
225                     :undefined
226                 }
227                 {
228                     !!this.props.click && !!this.props.form &&!!this.props.form.getFieldDecorator && !!this.props.dataValidationName
229                     && !!!this.props.keyValidationName?
230                     this.props.form.getFieldDecorator(this.props.dataValidationName, {
231                         initialValue:this.state.datas,
232                     })(<Input type="hidden"/>)
233                     :undefined
234                 }
235             </Fragment>
236          );
237     }
238 }
239 export default TagOpt;

 

效果:

 

 

 

 

也可以在普通页面中调用:

 

 获取值

 

 效果:

posted @ 2019-12-27 17:57  不老梦  阅读(1302)  评论(0编辑  收藏  举报