欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

自创ant-design-pro组件

程序员文章站 2023-08-23 11:25:07
ant design蚂蚁金服基于react打造的一个服务于企业级产品的UI框架。而ant design pro呢?就是基于Ant Design这个框架搭建的中后台管理控制台的脚手架。 话不多说,今天给大家分享一个自己写的一个组件。 源码如下: index.tsx文件: index.less文件: A ......

ant design蚂蚁金服基于react打造的一个服务于企业级产品的ui框架。而ant design pro呢?就是基于ant design这个框架搭建的中后台管理控制台的脚手架。

话不多说,今天给大家分享一个自己写的一个组件。

源码如下:

index.tsx文件:

  1 import react,{fragment} from 'react';
  2 import styles from './index.less'; 
  3 import undefined from '@/e2e/__mocks__/antd-pro-merge-less';
  4 export interface state {
  5     list:array<any>,
  6     cachelist:array<any>,
  7     eventif:boolean,
  8 }
  9 export interface props {
 10      style?:any,
 11      styleson?:any,
 12      val?:valfrom,
 13      datasource?:array<datasource>,
 14      onclickson?:any,
 15      onmouseenterson?:any,
 16      onmouseleaveson?:any
 17  }
 18 interface valfrom{
 19     type?:type|string,//动画类型
 20     direction?:direction|string,//方向
 21     time?:number,//时间 单位s
 22     delay?:number,//动画执行前的延时时间 单位s
 23     sondelay?:number//列表子项动画延时
 24     domid?:string,//事件绑定dom id
 25     event?:event|string,//动画执行事件
 26     hidemodel?:boolean//背景是否显示
 27 
 28 } 
 29 export const enum type{fadein}
 30 export const enum direction{top,buttom,left,regist,topleft,topregist,buttomleft,buttomregist}
 31 export const enum event{click,mouseenter}
 32 interface datasource{keys:any,title:any,style?:any}
 33 export class father extends react.component<props, state> {
 34     constructor(props: props) {
 35         super(props);
 36         this.state = { 
 37             list:[],//列表项
 38             cachelist:[],//暂时存储,观望是否绑定dom
 39             eventif:false,//是否触发了event事件
 40         };
 41         if(this.props.val !== undefined){
 42             const val:valfrom = this.props.val;
 43             if(this.props.val.type != undefined && !(val.type===type.fadein || val.type==="fadein")){
 44                 throw error(`type定义错误:错误值为 ${val.type},type取值为{enum:type,'fadein'}`,);
 45             }
 46             if(this.props.val.direction != undefined && !(val.direction === direction.top || val.direction === direction.buttom || 
 47                 val.direction === direction.left||val.direction === direction.regist || val.direction === direction.topleft ||
 48                 val.direction === direction.topregist || val.direction === direction.buttomleft || val.direction === direction.buttomregist ||
 49                 val.direction === 'top' || val.direction === 'buttom' || val.direction=== 'left' || val.direction === 'regist' ||
 50                 val.direction=== 'topleft' || val.direction === 'topregist' || val.direction === 'buttomleft' || val.direction === 'buttomregist')){
 51                 throw error(`direction定义错误:错误值为 ${val.direction},direction取值为{enum:direction,'top','buttom','left','regist',
 52                 'topleft','topregist','buttomleft','buttomregist'}`);
 53             }
 54             window.onload = function(){
 55                 if(val.domid !== undefined){    
 56                     if(document.getelementbyid(val.domid)===undefined || document.getelementbyid(val.domid)===null){
 57                         throw error(`指定id的dom元素不存在!`,);
 58                     }
 59                     if(val.event === undefined){
 60                         console.warn(`指定dom元素情况下未指定绑定事件event!`);
 61                     }
 62                 } 
 63             }
 64             if(val.event !== undefined){
 65                 if(!(val.event === event.click || val.event === event.mouseenter  || val.event === 'click' ||
 66                 val.event === 'mouseenter')){
 67                     throw error(`event定义错误:错误值为 ${val.event},event取值为{enum:event,'click','mouseenter'}`,);
 68                 }
 69                 if(val.domid === undefined){
 70                     console.warn(`绑定事件后未指定dom元素!`);
 71                 }
 72             }
 73         }  
 74     }
 75     iswidth=(strs:array<any>):number=>{
 76         let str : array<string> = [];
 77         for(let i=0;i<strs.length;i++){
 78             if(strs[i].type!==undefined && strs[i].type===son){
 79                 str.push(strs[i].props.children);
 80             }
 81         }
 82         let max:number = 0;
 83         let reg:regexp =  /[\u4e00-\u9fa5\uf900-\ufa2d]/i;
 84         str.foreach(element => {
 85             let formax = 0;
 86             for(let i=0;i<element.length;i++){
 87                 if(reg.test(element.charat(i))){
 88                     formax+=2;
 89                 }else{
 90                     formax++;
 91                 }
 92             }
 93             if(formax > max){
 94                 max = formax;
 95             }
 96         });
 97         return max;
 98     }
 99     iswidth1=(maxwidth:number,data:array<datasource>):number=>{
100         let max:number = maxwidth;
101         let reg:regexp =  /[\u4e00-\u9fa5\uf900-\ufa2d]/i;
102         data.foreach(element => {
103             let formax = 0;
104             for(let i=0;i<element.title.length;i++){
105                 if(reg.test(element.title.charat(i))){
106                     formax+=2;
107                 }else{
108                     formax++;
109                 }
110             }
111             if(formax > max){
112                 max = formax;
113             }
114         });
115         return max;
116     }
117     setlist=():void=>{
118         //清零
119         this.state.list.length = 0;
120         const list = [...this.state.cachelist];
121         this.setstate({list,eventif:true});
122         //解除绑定
123         if(this.props.val != undefined && this.props.val.domid != undefined){
124             let dom:any = document.getelementbyid(this.props.val.domid);
125             let event:string = "click";
126             if(this.props.val.event === event.mouseenter){
127                 event = "mouseenter";
128             }
129             dom.removeeventlistener(event,this.setlist);        
130         }
131     }
132     bindevent=(val:any):void=>{
133         if(this.props.val != undefined && this.props.val.domid != undefined && this.props.val.event != undefined){
134             const dom:any = document.getelementbyid(this.props.val.domid);
135             let event:string = "click";
136             if(this.props.val.event === event.mouseenter){
137                 event = "mouseenter";
138             }
139             dom.addeventlistener(event,this.setlist);                
140         }
141     }
142     render() { 
143         //默认动画效果
144         const defval:valfrom = {
145             type:type.fadein,
146             direction:direction.left,
147             time:.5,
148             sondelay:.1,
149             delay:0,
150         };
151         const defv = {...defval,...this.props.val}
152         //son项数
153         let index:number = 0;
154         //最大文字占格
155         let width:number=0;
156         //字体大小
157         let fontsize:number = 13;
158         //son高度
159         let formatheight:number = 26;
160         //father及son宽度
161         let formatwidth:number = 0;
162        
163         let sonstr:any = this.props.children;
164         // //宽高自适应
165         if(this.props.children != undefined){
166             width = this.iswidth(sonstr);
167         }
168         if(this.props.datasource != undefined){
169             width = this.iswidth1(width,this.props.datasource);
170         }
171         fontsize = this.props.style!==undefined && this.props.style.fontsize!==undefined?number.parseint(this.props.style.fontsize):13;
172         formatheight = fontsize*2;
173         formatwidth = fontsize*width*0.6;
174         
175         //绑定dom后是否隐藏模板
176         let hidemodel = "visible";
177         if(!this.state.eventif){
178             //清零
179             this.state.list.length = 0;
180             this.state.cachelist.length = 0;
181             //子项写入
182             if(this.props.children != null && this.props.children != undefined){  
183                 for(let i=0;i<sonstr.length;i++){
184                     if(sonstr[i].type!==undefined && sonstr[i].type===son){
185                         this.state.cachelist.push(<list title={sonstr[i].props.children} style={sonstr[i].props.style} styleson={this.props.styleson}
186                         animation={defv} index={index++} formatheight={formatheight}
187                         formatwidth = {formatwidth} keys={this.props.children[i].props.keys !==undefined?
188                         this.props.children[i].props.keys:number.max_value-i} onclick={this.props.children[i].props.onclick}
189                         onclickson={this.props.onclickson} onmouseenter={this.props.children[i].props.onmouseenter}
190                         onmouseenterson={this.props.onmouseenterson} onmouseleave={this.props.children[i].props.onmouseleave}
191                         onmouseleaveson={this.props.onmouseleaveson}/>);
192                     }
193                 }
194             }
195             if(this.props.datasource !== undefined){
196                 for(let i=0;i<this.props.datasource.length;i++){
197                     this.state.cachelist.push(<list title={this.props.datasource[i].title} style={this.props.datasource[i].style} index={index++}
198                     styleson={this.props.styleson} animation={defv} formatheight={formatheight} formatwidth = {formatwidth} keys=
199                     {this.props.datasource[i].keys}/>);
200                 }
201             }
202             //无dom绑定
203             if(defv.domid ===undefined || defv.event ===undefined){
204                 for(let i =0;i<this.state.cachelist.length;i++){
205                     this.state.list.push(this.state.cachelist[i]);
206                 }
207                 
208             }else{
209                 //有dom绑定
210                 if(this.props.val!=undefined && this.props.val.hidemodel){
211                     hidemodel = "hidden";
212                 }
213                 //事件绑定
214                 const _this  = this;
215                 //切换菜单后window.onload不会执行,但dom已经重置
216                 if(this.props.val != undefined && this.props.val.domid != undefined && this.props.val.event != undefined && 
217                 document.getelementbyid(this.props.val.domid)==null){
218                     let interval = window.setinterval(()=>{
219                         let dom:any = null;
220                         if(_this.props.val!=undefined && _this.props.val.domid != undefined){
221                             dom = document.getelementbyid(_this.props.val.domid);
222                         }
223                         if(dom !== null && dom !==undefined && dom !=="null"){
224                             _this.bindevent(defv);
225 
226                             window.clearinterval(interval); 
227                         } 
228                     }, 100);        
229                 }
230             }
231         }else {
232             index = this.state.list.length;
233         }
234         
235         //father默认样式
236 
237         const deffatherstyle:any = {
238             border:"1px solid #91d5ff",
239             backgroundcolor: "#e6f7ff",
240             fontsize:"13px",
241             color:"#000",
242             paddimg:`${fontsize}px`,
243             height: `${formatheight*index+2}px`,
244             width:`${formatwidth+2}px`,
245             visibility:`${hidemodel}`
246         }
247         const style = {...deffatherstyle,...this.props.style};
248         return (
249             <fragment>
250                 <div style={style} classname={styles.fdiv}>
251                     <ul classname={styles.ul}>
252                         {this.state.list}
253                     </ul>
254                 </div>
255             </fragment>
256          );
257     }
258 }
259 export class son extends react.component<{style?:any,keys?:any,onclick?:any,onmouseenter?:any,onmouseleave?:any}, {}> {
260 }
261 class list extends react.component<{title:string,style?:any,styleson?:any,animation:valfrom,keys:any,index:number,formatheight:number,
262     formatwidth:number,onclick?:any,onclickson?:any,onmouseenter?:any,onmouseenterson?:any,onmouseleave?:any,onmouseleaveson?:any},{}> {
263     click = (key:any,title:any)=>{
264         if(this.props.onclick !== undefined){
265             this.props.onclick(key,title);
266         }else if(this.props.onclickson !== undefined){
267             this.props.onclickson(key,title);
268         }
269     }
270     mouseenter = (key:any,title:any)=>{
271         if(this.props.onmouseenter !== undefined){
272             this.props.onmouseenter(key,title);
273         }else if(this.props.onmouseenterson !== undefined){
274             this.props.onmouseenterson(key,title);
275         }
276     }
277     mouseleave = (key:any,title:any)=>{
278         if(this.props.onmouseleave !== undefined){
279             this.props.onmouseleave(key,title);
280         }else if(this.props.onmouseleaveson !== undefined){
281             this.props.onmouseleaveson(key,title);
282         }
283     }
284 
285 
286 
287     render() {
288         const val:valfrom = this.props.animation;
289         const style = {animation:'',animationdelay:'0s'};
290         
291         //加载页面后直接执行
292         if(val.type === type.fadein && val.direction === direction.top || val.type === 'fadein' && val.direction === 'top'
293         || val.type === type.fadein && val.direction === 'top' || val.type === 'fadein' && val.direction === direction.top){
294             style.animation= `${styles.fadeintop} ${val.time}s forwards`;
295         }else if(val.type === type.fadein && val.direction === direction.buttom || val.type === 'fadein' && val.direction === 'buttom'
296         || val.type === type.fadein && val.direction === 'buttom' || val.type === 'fadein' && val.direction === direction.buttom){
297             style.animation = `${styles.fadeinbuttom} ${val.time}s forwards`;       
298         }else if(val.type === type.fadein && val.direction === direction.left || val.type === 'fadein' && val.direction === 'left'
299         || val.type === type.fadein && val.direction === 'left' || val.type === 'fadein' && val.direction === direction.left){
300         style.animation = `${styles.fadeinleft} ${val.time}s forwards`;
301         }else if(val.type === type.fadein && val.direction === direction.regist || val.type === 'fadein' && val.direction === 'regist'
302         || val.type === type.fadein && val.direction === 'regist' || val.type === 'fadein' && val.direction === direction.regist){
303             style.animation = `${styles.fadeinregist} ${val.time}s forwards`;
304         }else if(val.type === type.fadein && val.direction === direction.topleft || val.type === 'fadein' && val.direction === 'topleft'
305         || val.type === type.fadein && val.direction === 'topleft' || val.type === 'fadein' && val.direction === direction.topleft){
306             style.animation = `${styles.fadeintopleft} ${val.time}s forwards`;
307         }else if(val.type === type.fadein && val.direction === direction.topregist || val.type === 'fadein' && val.direction === 'topregist'
308         || val.type === type.fadein && val.direction === 'topregist' || val.type === 'fadein' && val.direction === direction.topregist){
309             style.animation = `${styles.fadeintopregist} ${val.time}s forwards`;
310         }else if(val.type === type.fadein && val.direction === direction.buttomleft || val.type === 'fadein' && val.direction === 'buttomleft'
311         || val.type === type.fadein && val.direction === 'buttomleft' || val.type === 'fadein' && val.direction === direction.buttomleft){
312             style.animation = `${styles.fadeinbuttomleft} ${val.time}s forwards`;
313         }else if(val.type === type.fadein && val.direction === direction.buttomregist || val.type === 'fadein' && val.direction === 'buttomregist'
314         || val.type === type.fadein && val.direction === 'buttomregist' || val.type === 'fadein' && val.direction === direction.buttomregist){
315             style.animation = `${styles.fadeinbuttomregist} ${val.time}s forwards`;
316         }
317         if(val.sondelay !== undefined && val.delay !== undefined){
318             style.animationdelay = `${this.props.index*val.sondelay+val.delay}s`;
319         }
320         //son默认样式
321         const defstyle:any = {
322             textalign: "center",
323             width:`${this.props.formatwidth}px`,
324             height:`${this.props.formatheight}px`,
325             lineheight:`${this.props.formatheight}px`,
326         }
327         const sty = {...defstyle,...this.props.styleson,...this.props.style,...style};
328         return ( 
329             <li classname={styles.li} style={sty} key={this.props.keys} onclick={this.click.bind(this,this.props.keys,this.props.title)}
330             onmouseenter = {this.mouseenter.bind(this,this.props.keys,this.props.title)} onmouseleave=
331             {this.mouseleave.bind(this,this.props.keys,this.props.title)}>{this.props.title}</li>
332          );
333     }
334 }

index.less文件:

  1 @top:200px;
  2 @left:400px;
  3 .fdiv,.li,.ul,body,div{
  4     padding: 0px;
  5     margin: 0px;
  6     border: 0px;
  7 }
  8 .fdiv{
  9     position: relative;
 10 }
 11 .li{
 12     list-style:none;
 13     visibility:hidden;
 14     cursor: pointer; 
 15 }
 16 li:hover{
 17     background-color: #a1e5ff;
 18 }
 19 .ul{
 20     position: absolute;
 21     z-index: 999;
 22     display: inline-block;
 23 }
 24 @keyframes fadeintop{
 25     0%{
 26         opacity: 0;
 27         margin-top: @top;
 28         visibility:visible;
 29     }
 30     100%{
 31         opacity: 1;
 32         margin-top: 0px;
 33         visibility:visible;
 34     }
 35 }
 36 @keyframes fadeinbuttom{
 37     0%{
 38         opacity: 0;
 39         margin-top: -@top;
 40         visibility:visible;
 41     }
 42     100%{
 43         opacity: 1;
 44         margin-top: 0px;
 45         visibility:visible;
 46     }
 47 }
 48 @keyframes fadeinleft{
 49     0%{
 50         opacity: 0;
 51         margin-left: @left;
 52         visibility:visible;
 53     }
 54     100%{
 55         opacity: 1;
 56         margin-left: 0px;
 57         visibility:visible;
 58     }
 59 }
 60 @keyframes fadeinregist{
 61     0%{
 62         opacity: 0;
 63         margin-left: -@left;
 64         visibility:visible;
 65     }
 66     100%{
 67         opacity: 1;
 68         margin-left: 0px;
 69         visibility:visible;
 70     }
 71 }
 72 @keyframes fadeintopleft{
 73     0%{
 74         opacity: 0;
 75         margin-top: @top;
 76         margin-left: @left;
 77         visibility:visible;
 78     }
 79     100%{
 80         opacity: 1;
 81         margin-top: 0px;
 82         margin-left: 0px;
 83         visibility:visible;
 84     }
 85 }
 86 @keyframes fadeintopregist{
 87     0%{
 88         opacity: 0;
 89         margin-top: @top;
 90         margin-left: -@left;
 91         visibility:visible;
 92     }
 93     100%{
 94         opacity: 1;
 95         margin-top: 0px;
 96         margin-left: 0px;
 97         visibility:visible;
 98     }
 99 }
100 @keyframes fadeinbuttomleft{
101     0%{
102         opacity: 0;
103         margin-top: -@top;
104         margin-left: @left;
105         visibility:visible;
106     }
107     100%{
108         opacity: 1;
109         margin-top: 0px;
110         margin-left: 0px;
111         visibility:visible;
112     }
113 }
114 @keyframes fadeinbuttomregist{
115     0%{
116         opacity: 0;
117         margin-top: -@top;
118         margin-left: -@left;
119         visibility:visible;
120     }
121     100%{
122         opacity: 1;
123         margin-top: 0px;
124         margin-left: 0px;
125         visibility:visible;
126     }
127 }

api如下:

自创ant-design-pro组件

自创ant-design-pro组件