自创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如下:
推荐阅读
-
django中的ajax组件教程详解
-
WindowsXp系统提示YJT.exe-无法找到组件的故障原因及两种解决方法
-
微信小程序使用map组件实现解析经纬度功能示例
-
微信小程序使用map组件实现路线规划功能示例
-
微信小程序使用map组件实现检索(定位位置)周边的POI功能示例
-
微信小程序map组件结合高德地图API实现wx.chooseLocation功能示例
-
Android自定义View设定到FrameLayout布局中实现多组件显示的方法 分享
-
深入理解Vue父子组件生命周期执行顺序及钩子函数
-
vue组件横向树实现代码
-
基于vue-upload-component封装一个图片上传组件的示例