在ant design 的form組件中 能用於提交的組件比較少,所以我在這寫了一個可以單選、多選標簽提交的組件,調用非常簡單。 代碼: 1 import React,{Fragment} from 'react'; 2 import { Tag,Icon,Input } from 'antd'; ...
在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,//菜單驗證方法 14 dataValidationName?:string,//設置提交名稱,若用此參數提交則提交選中的data,用於菜單提交獲取 15 keyValidationName?:string,//設置提交名稱,若用此參數提交則提交選中的key,用於菜單提交獲取 16 notNull?:boolean,//選項不能為空 17 } 18 19 export interface State { 20 //tagData:TagDataType | undefined, 21 keys:string, 22 datas:string, 23 styleState:number | Array<number>, 24 } 25 26 class TagOpt extends React.Component<Props, State> { 27 constructor(props: Props) { 28 super(props); 29 //驗證傳入數據的合法性 30 if(this.props.notNull && !!!this.props.defaultKey){ 31 throw Error('TagOpt選中項為空,設置defaultKey!'); 32 } 33 if(!!this.props.form && !!!this.props.keyValidationName && !!!this.props.dataValidationName){ 34 throw Error('若要使用form提交,請設置keyValidationName或dataValidationName!'); 35 } 36 this.state=this.setDefaultVal(); 37 } 38 //滑鼠點擊標簽事件 39 TagClick = (tagData:TagDataType,index:number) =>{ 40 if(this.props.click !== undefined && this.props.click){ 41 if(this.props.checkbox){ 42 const optIf = this.optIf(index); 43 let styleState:Array<number> = new Array();; 44 if(typeof this.state.styleState === 'object'){ 45 styleState = [...this.state.styleState]; 46 }else{ 47 styleState = [this.state.styleState]; 48 } 49 if(optIf.state){ 50 //點擊已選擇 51 //如果設置不為空且選中選項大於1或者沒有設置不為空選項 52 //則清空 53 if(this.props.notNull && styleState.length>1 || !!!this.props.notNull){ 54 styleState.splice(optIf.index,1); 55 this.setState({ 56 keys:this.moveSubString(this.state.keys,tagData.key), 57 datas:this.moveSubString(this.state.datas,tagData.data), 58 styleState 59 },()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')}); 60 } 61 }else{ 62 //點擊未選擇 63 styleState.splice(styleState.length,0,index); 64 this.setState({ 65 keys:this.addSubString(this.state.keys,tagData.key), 66 datas:this.addSubString(this.state.datas,tagData.data), 67 styleState 68 },()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')}); 69 } 70 }else{ 71 if(this.state.styleState === index){ 72 //點擊已選擇 73 //若設置可以為空 74 //則清空 75 if(!!!this.props.notNull){ 76 this.setState({keys:'',datas:'',styleState:this.props.data.length} 77 ,()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')}); 78 } 79 }else{ 80 //點擊未選擇 81 this.setState({keys:tagData.key,datas:tagData.data,styleState:index} 82 ,()=>{this.setVal(this.state.datas,'data');this.setVal(this.state.keys,'key')}); 83 } 84 } 85 } 86 } 87 //返回移出指定子串的字元串,移出所有重覆子串 88 moveSubString = (str:string,subString:string):string => { 89 let array:Array<string> = str.split(','); 90 for(let i=0;i<array.length;i++){ 91 if(array[i] === subString){ 92 array.splice(i,1); 93 } 94 } 95 return array.toString(); 96 } 97 //返回增加子串的字元串,重覆則不增加 98 addSubString = (str:string,subString:string|Array<string>) =>{ 99 if(typeof subString === 'string'){ 100 let comma = str !==''?',':''; 101 return str +comma+subString; 102 }else{ 103 let s:string = str; 104 for(let i=0;i<subString.length;i++){ 105 let comma = s !==''?',':''; 106 s+=comma+subString[i]; 107 } 108 return s; 109 } 110 } 111 //選擇判斷 112 optIf = (index:number):{state:boolean,index:number} => { 113 if(typeof this.state.styleState ==='number'){ 114 return {state:this.state.styleState === index,index:0}; 115 }else{ 116 let falg:boolean = false; 117 const styleState = this.state.styleState; 118 let i=0; 119 for(;i<styleState.length;i++){ 120 if(styleState[i] === index){ 121 falg = true; 122 break; 123 } 124 } 125 return {state:falg,index:i}; 126 } 127 } 128 //寫入表單 129 setVal = (data:string,type:string) => { 130 if(this.props.form != undefined){ 131 let json:object = {} 132 if(type === 'data'){ 133 if(this.props.dataValidationName !== undefined){ 134 json[this.props.dataValidationName] = data; 135 this.props.form.setFieldsValue(json); 136 } 137 }else if(type === 'key'){ 138 if(this.props.keyValidationName !== undefined){ 139 json[this.props.keyValidationName] = data; 140 this.props.form.setFieldsValue(json); 141 } 142 } 143 } 144 } 145 //預設值轉換 146 setDefaultVal=():State=>{ 147 if(this.props.checkbox){ 148 //多選框,值為1個或數組 149 let styleState:Array<number> = new Array(); 150 let keys:Array<string> = new Array(); 151 let datas:Array<string> = new Array(); 152 const {defaultKey,data} = this.props; 153 if(typeof defaultKey === 'object'){ 154 for(let i=0;i<defaultKey.length;i++){ 155 for(let j=0;j<data.length;j++){ 156 if(defaultKey[i] === data[j].key){ 157 styleState.push(i); 158 keys.push(data[j].key); 159 datas.push(data[j].data); 160 } 161 } 162 } 163 return { 164 keys:this.addSubString('',keys), 165 datas:this.addSubString('',datas), 166 styleState 167 } 168 }else{ 169 let i:number = 0; 170 let key:string = ''; 171 let dat:string = ''; 172 for(;i<data.length;i++){ 173 if(data[i].key === defaultKey){ 174 key=data[i].key; 175 dat=data[i].data; 176 break; 177 } 178 } 179 return { keys:key,datas:dat,styleState: i }; 180 } 181 }else if(this.props.checkbox === undefined && typeof this.props.defaultKey ==='string' || 182 !this.props.checkbox && typeof this.props.defaultKey ==='string'){ 183 //多選未設置且預設值為1個或單選且預設值為一個 184 let i:number = 0; 185 let key:string = ''; 186 let dat:string = ''; 187 if(this.props.defaultKey !== undefined){ 188 const data = this.props.data; 189 for(;i<data.length;i++){ 190 if(data[i].key === this.props.defaultKey){ 191 key=data[i].key; 192 dat=data[i].data; 193 break; 194 } 195 } 196 } 197 return { keys:key,datas:dat,styleState: i }; 198 }else if(this.props.defaultKey === undefined || this.props.defaultKey === '' || this.props.defaultKey === []){ 199 if(this.props.checkbox){ 200 return { keys:'',datas:'',styleState: [] }; 201 }else{ 202 return { keys:'',datas:'',styleState: this.props.data.length }; 203 } 204 }else{ 205 return {keys:'',datas:'',styleState: this.props.data.length}; 206 } 207 } 208 render() { 209 const content:any = this.props.data.map((tagData:TagDataType,index:number)=>{ 210 const cursor:any = this.props.click !== undefined && this.props.click ?'pointer':'default'; 211 return( 212 <Tag color={tagData.color} key={tagData.key} onClick={this.TagClick.bind(this,tagData,index)} style={{cursor}}> 213 {tagData.data} 214 {this.optIf(index).state?<Icon type="check" />:undefined} 215 </Tag> 216 ) 217 }); 218 return ( 219 <Fragment> 220 {content} 221 { 222 !!this.props.click && !!this.props.form && !!this.props.form.getFieldDecorator && !!this.props.keyValidationName? 223 this.props.form.getFieldDecorator(this.props.keyValidationName, { 224 initialValue:this.state.keys, 225 })(<Input type="hidden"/>) 226 :undefined 227 } 228 { 229 !!this.props.click && !!this.props.form &&!!this.props.form.getFieldDecorator && !!this.props.dataValidationName 230 && !!!this.props.keyValidationName? 231 this.props.form.getFieldDecorator(this.props.dataValidationName, { 232 initialValue:this.state.datas, 233 })(<Input type="hidden"/>) 234 :undefined 235 } 236 </Fragment> 237 ); 238 } 239 } 240 export default TagOpt;
效果: