封裝一個漂亮的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;

 

效果:

 

 

 

 

也可以在普通頁面中調用:

 

 獲取值

 

 效果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM