自創ant-design-pro組件

来源:https://www.cnblogs.com/chengpu/archive/2019/10/11/web1.html
-Advertisement-
Play Games

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 }
	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近在寫一個類似於vue的一種cola-ui框架,有興趣的朋友可以瞭解一下:http://legacy.cola-ui.com/; 項目中有個業務需要引入Echarts圖表的需求,由於是前後端沒有分離,當時就沒考慮用npm去下載,在官網下載了一個echarts.min.js; 我這邊是用vscode ...
  • <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>jianpan</title></head><body><table border="2"> <thead> <th>option</th> <th>name</t ...
  • 一、vue-resource 1、簡介 一款vue插件,用於處理ajax請求,vue1.x時廣泛應用,現不被維護。 2、使用流程 step1:安裝 step2:引入 step3:編碼 step4:完整代碼 step5:截圖: 請求正常 點擊鏈接跳轉 使用錯誤的地址 彈出錯誤提示框 二、axios 1 ...
  • 使用jq寫選項卡,告別了繁瑣的迴圈以及命名規範 基本原理: 1.當某一個btn被選中時,將這個btn的背景顏色設為橘色,其餘兄弟btn背景顏色設為空(none) 2.如果子div與btn的索引相同,就將這個div顯示而其他兄弟div隱藏 1).css函數參數2的回調函數方法; 2).原生get方法再 ...
  • 我們知道,在創建一個函數時如果要用到變數來存取信息的話,要儘量使用局部變數。 因為一方面局部變數會隨著函數的執行結束被銷毀;另一方面在不執行函數的時候也不會創建這個局部變數,對節省空間資源有很大的好處。 下麵我們來看一個案例: 上面這個案例里的變數num就是一個典型的全局變數。 那麼我們要怎麼把nu ...
  • map()是underscore.js中一個處理數組和對象的方法。 params: 1. array || obj 2. callback 3. content 上下文指向 使用: 這個代碼如果我自己寫的話當然很簡單的想法了,就是判斷傳入參數類型,進行遍歷,然後判斷是否有回調,有的話,就執行,並將結 ...
  • 方法一: 新建個 Android studio 項目,用 webview 指定訪問你的頁面 方法二: 使用工具 cordova 附上地址:http://cordova.axuer.com/docs/zh-cn/latest/guide/platforms/android/index.html 方法三 ...
  • 我們在編寫網頁代碼時,首先應該做的就是設計好頁面的佈局形式,然後再往裡面填充內容。網頁佈局的好與壞,直接決定了網頁最終的展示效果。PC端常見的網頁佈局形式有兩列佈局、三列佈局等。在CSS中,我們通常使用浮動(float)、定位(position)、顯示模式(display)相關屬性結合使用,以達到預 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...