自写一个ant-design-pro AnimationList组件_莺语_前端开发者

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

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 }
  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 }

1fromreact;
2from./index.less;
3from@/e2e/__mocks__/antd-pro-merge-less;
4interface State {
5,
6,
7 eventIF:boolean,
8}
9interface Props {
10:any,
11:any,
12:valFrom,
13,
14:any,
15:any,
16:any
17 }
18interface valFrom{
19string//动画类型 20string//方向 21//时间 单位s 22//动画执行前的延时时间 单位s 23//列表子项动画延时 24string//事件绑定dom id 25eventstring//动画执行事件 26//背景是否显示 27 28}
29constenum TYPE{FADEIN}
30constenum DIRECTION{TOP,BUTTOM,LEFT,REGIST,TOPLEFT,TOPREGIST,BUTTOMLEFT,BUTTOMREGIST}
31constenum EVENT{CLICK,MOUSEENTER}
32interface:any}
33class {
34 constructor(props: Props) {
35 super(props);
36this {
37//列表项 38//暂时存储,观望是否绑定dom 39false//是否触发了event事件 40 };
41ifthis undefined){
42constthis.props.val;
43ifthisfadeIn)){
44throwenumfadeIn}`,);
45 }
46ifthis 47 48 49topbuttomleftregist 50topLefttopRegistbuttomLeftbuttomRegist)){
51throwenumtopbuttomleftregist,
52topLefttopRegistbuttomLeftbuttomRegist}`);
53 }
54 function(){
55if undefined){
56ifnull){
57throw Error(`指定id的DOM元素不存在!`,);
58 }
59ifevent undefined){
60 console.warn(`指定DOM元素情况下未指定绑定事件event!`);
61 }
62 } 
63 }
64ifevent undefined){
65ifeventeventeventclick 66eventmouseEnter)){
67throweventenumclickmouseEnter}`,);
68 }
69if undefined){
70 console.warn(`绑定事件后未指定DOM元素!`);
71 }
72 }
73 }
74 }
75{
76string [];
77for0){
78ifSon){
79 str.push(strs[i].props.children);
80 }
81 }
820;
83i;
84 {
850;
86for0){
87if(reg.test(element.charAt(i))){
882;
89else{
90;
91 }
92 }
93if max){
94 forMax;
95 }
96 });
97return max;
98 }
99{
100 maxWidth;
101i;
102 {
1030;
104for0){
105if(reg.test(element.title.charAt(i))){
1062;
107else{
108;
109 }
110 }
111if max){
112 forMax;
113 }
114 });
115return max;
116 }
117void{
118//清零119this0;
120constthis.state.cacheList];
121thistrue});
122//解除绑定123ifthisthis undefined){
124this.props.val.domId);
125eventstringclick;
126ifthisevent EVENT.MOUSEENTER){
127eventmouseenter;
128 }
129eventthis.setList);
130 }
131 }
132void{
133ifthisthisthisevent undefined){
134constthis.props.val.domId);
135eventstringclick;
136ifthisevent EVENT.MOUSEENTER){
137eventmouseenter;
138 }
139eventthis.setList);
140 }
141 }
142 render() {
143//默认动画效果144const {
145 type:TYPE.FADEIN,
146 direction:DIRECTION.LEFT,
1475,
1481,
1490,
150 };
151constthis.props.val}
152//Son项数1530;
154//最大文字占格1550;
156//字体大小15713;
158//Son高度15926;
160//Father及Son宽度1610;
162163this.props.children;
164////宽高自适应165ifthis undefined){
166this.isWidth(sonStr);
167 }
168ifthis undefined){
169thisthis.props.dataSource);
170 }
171thisthisthis13;
1722;
1730.6;
174175//绑定dom后是否隐藏模板176visible;
177ifthis.state.eventIF){
178//清零179this0;
180this0;
181//子项写入182ifthisnullthis undefined){
183for0){
184ifSon){
185thisthis.props.styleSon}
186{formatHeight}
187this188thisthis.props.children[i].props.onClick}
189thisthis.props.children[i].props.onMouseEnter}
190thisthis.props.children[i].props.onMouseLeave}
191this);
192 }
193 }
194 }
195ifthis undefined){
196for0this){
197thisthisthis}
198this199this);
200 }
201 }
202//无dom绑定203ifeventundefined){
204for0this){
205thisthis.state.cacheList[i]);
206 }
207208else{
209//有dom绑定210ifthisthis.props.val.hideModel){
211hidden;
212 }
213//事件绑定214constthis;
215//切换菜单后window.onload不会执行,但dom已经重置216ifthisthisthisevent217thisnull){
218{
219null;
220if undefined){
221 document.getElementById(_this.props.val.domId);
222 }
223ifnullnull){
224 _this.bindEvent(defV);
225226 window.clearInterval(interval);
227 }
228100);
229 }
230 }
231else {
232this.state.list.length;
233 }
234235//Father默认样式236237const {
2381px solid #91D5FF,
239#E6F7FF,
24013px,
241#000,
242 paddimg:`${fontSize}px`,
2432}px`,
2442}px`,
245 visibility:`${hideModel}`
246 }
247constthis.props.style};
248return (
249250251252this.state.list}
253254255256 );
257 }
258}
259class {
260}
261classstring:any,animation:valFrom,keys:any,index:number,formatHeight:number,
262 {
263{
264ifthis undefined){
265this.props.onClick(key,title);
266elseifthis undefined){
267this.props.onClickSon(key,title);
268 }
269 }
270{
271ifthis undefined){
272this.props.onMouseEnter(key,title);
273elseifthis undefined){
274this.props.onMouseEnterSon(key,title);
275 }
276 }
277{
278ifthis undefined){
279this.props.onMouseLeave(key,title);
280elseifthis undefined){
281this.props.onMouseLeaveSon(key,title);
282 }
283 }
284285286287 render() {
288constthis.props.animation;
289const0s};
290291//加载页面后直接执行292iffadeIntop293topfadeIn DIRECTION.TOP){
294 `${styles.fadeInTop} ${val.time}s forwards`;
295elseiffadeInbuttom296buttomfadeIn DIRECTION.BUTTOM){
297 `${styles.fadeInButtom} ${val.time}s forwards`;
298elseiffadeInleft299leftfadeIn DIRECTION.LEFT){
300 `${styles.fadeInLeft} ${val.time}s forwards`;
301elseiffadeInregist302registfadeIn DIRECTION.REGIST){
303 `${styles.fadeInRegist} ${val.time}s forwards`;
304elseiffadeIntopLeft305topLeftfadeIn DIRECTION.TOPLEFT){
306 `${styles.fadeInTopLeft} ${val.time}s forwards`;
307elseiffadeIntopRegist308topRegistfadeIn DIRECTION.TOPREGIST){
309 `${styles.fadeInTopRegist} ${val.time}s forwards`;
310elseiffadeInbuttomLeft311buttomLeftfadeIn DIRECTION.BUTTOMLEFT){
312 `${styles.fadeInButtomLeft} ${val.time}s forwards`;
313elseiffadeInbuttomRegist314buttomRegistfadeIn DIRECTION.BUTTOMREGIST){
315 `${styles.fadeInButtomRegist} ${val.time}s forwards`;
316 }
317if undefined){
318thisval.delay}s`;
319 }
320//Son默认样式321const {
322center,
323this.props.formatWidth}px`,
324this.props.formatHeight}px`,
325this.props.formatHeight}px`,
326 }
327constthisthis.props.style,…style};
328return (
329thisthisthisthisthis.props.title)}
330thisthisthisthis331thisthisthisthisthis332 );
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 }
  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 }

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{
12style:none;
13 visibility:hidden;
14 cursor: pointer;
15}
16li:hover{
17color: #A1E5FF;
18}
19.ul{
20 position: absolute;
21999;
22block;
23}
24@keyframes fadeInTop{
250{
260;
27top: @top;
28 visibility:visible;
29 }
30100{
311;
32top: 0px;
33 visibility:visible;
34 }
35}
36@keyframes fadeInButtom{
370{
380;
39@top;
40 visibility:visible;
41 }
42100{
431;
44top: 0px;
45 visibility:visible;
46 }
47}
48@keyframes fadeInLeft{
490{
500;
51left: @left;
52 visibility:visible;
53 }
54100{
551;
56left: 0px;
57 visibility:visible;
58 }
59}
60@keyframes fadeInRegist{
610{
620;
63@left;
64 visibility:visible;
65 }
66100{
671;
68left: 0px;
69 visibility:visible;
70 }
71}
72@keyframes fadeInTopLeft{
730{
740;
75top: @top;
76left: @left;
77 visibility:visible;
78 }
79100{
801;
81top: 0px;
82left: 0px;
83 visibility:visible;
84 }
85}
86@keyframes fadeInTopRegist{
870{
880;
89top: @top;
90@left;
91 visibility:visible;
92 }
93100{
941;
95top: 0px;
96left: 0px;
97 visibility:visible;
98 }
99}
100@keyframes fadeInButtomLeft{
1010{
1020;
103@top;
104left: @left;
105 visibility:visible;
106 }
107100{
1081;
109top: 0px;
110left: 0px;
111 visibility:visible;
112 }
113}
114@keyframes fadeInButtomRegist{
1150{
1160;
117@top;
118@left;
119 visibility:visible;
120 }
121100{
1221;
123top: 0px;
124left: 0px;
125 visibility:visible;
126 }
127

API如下:

API如下:

注意:动画进入选择的类型目前只有fadeIn(渐入),有人可能会说这个可以不要,但是如果要继续拓展的话这个属性就必不可少了,比如拓展增强、轨迹、旋转、无效果等。这些拓展稍显有些麻烦,由于我只是当练习react与typescript来写就没有拓展,但不是不能拓展。

注意:动画进入选择的类型目前只有fadeIn(渐入),有人可能会说这个可以不要,但是如果要继续拓展的话这个属性就必不可少了,比如拓展增强、轨迹、旋转、无效果等。这些拓展稍显有些麻烦,由于我只是当练习react与typescript来写就没有拓展,但不是不能拓展。注意:动画进入选择的类型目前只有fadeIn(渐入),有人可能会说这个可以不要,但是如果要继续拓展的话这个属性就必不可少了,比如拓展增强、轨迹、旋转、无效果等。这些拓展稍显有些麻烦,由于我只是当练习react与typescript来写就没有拓展,但不是不能拓展。

» 本文来自:前端开发者 » 《自写一个ant-design-pro AnimationList组件_莺语_前端开发者》
» 本文链接地址:https://www.rokub.com/73575.html
» 您也可以订阅本站:https://www.rokub.com
赞(0)
64K

评论 抢沙发

评论前必须登录!