zoukankan      html  css  js  c++  java
  • 封装一个漂亮的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;

    效果:

     

     

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

     获取值

     效果:

  • 相关阅读:
    LinkedList类源码浅析(一)
    ArrayList类源码浅析(三)
    我谁也没等,因为谁也不会来
    维持一段友谊
    最甜美的悲伤
    小美人访谈录笔记[1]
    1984我想对这个世界说些什么
    我喜欢我
    等不来的始终等不来,无须报以希望
    我抱有怀疑
  • 原文地址:https://www.cnblogs.com/chengpu/p/web4.html
Copyright © 2011-2022 走看看