更新時間:2018-11-16 來源:黑馬程序員技術社區(qū) 瀏覽量:
TypeScript 入門,寫一個 react 進度條組件寫在最前面如果你寫過 react 的組件, 這篇文章對與你來說基本沒有什么難度。純粹的是加上了一點 ts 的知識。我完全是以學習者的姿態(tài)來描述我寫組件的過程,很多不嚴謹的地方請大家指出來哈哈。
看看實現的效果-gif 動圖效果
這是一個普通的 UI 組件,難點主要在設計(css)上面。
需求:分步驟進行的一個精度條,我們只需要輸入參數,step 和 total 來計算出百分比然后顯示就 ok 了。
/** @param step 第幾步* @param total 總共的步驟* @param showInfo 是否需要顯示百分比提示* @param color 可以自定義顏色*/復制代碼說了這么多開始動手吧環(huán)境配置方面就略過了,這里我們直接來寫代碼
需要配置 node,ts,less 環(huán)境
1、在你的 componments 文件下創(chuàng)建一個 progressBar 文件夾。tsx 是 react下特殊 ts 文件。 然后在 progressBar 下面繼續(xù)添加 index.tsx 和 style.less
-- componments -- progressBar -- index.tsx -- style.less復制代碼index.tsx2、先引進必須的組件
import React, { Component } from 'react';import * as PropTypes from 'prop-types';import './style.less';// 定義接口 export interface IProgressProps{ }// 定義類class ProgressBar extends Component<IProgressProps> {}export default ProgressBar;復制代碼要點: IProgressProps ,使用 pascal 命名,用 I打頭,Props 是代表這個接口參數支持。
3、根據我們上面需求的分析,我們來定義 interface,定義類的 propTypes 和 defalutProps
export interface IProgressProps { // prefixCls 為了以后樣式統一設置的 classname prefixCls?: string; step?: number; total?: number; showInfo?: boolean; color?: string;}class ProgressBar extends Component<IProgressProps> { //設置默認值 static defaultProps = { prefixCls: 'demo-progress', step: 2, total: 10, showInfo: false, color: '#FFE103' }; //設置類的參數類型 static propTypes = { prefixCls:PropTypes.string, step: PropTypes.number, total: PropTypes.number, showInfo: PropTypes.bool, color: PropTypes.string }; render(){ return( <div>progressBar</div> ) }}復制代碼要點: 其中的“ ?”表示可選,number 就是接口參數的類型。表示你輸入的必須是一個 number 類型,不然 ts 會報錯。這里我們可以引用一下 progressBar 模塊,看看成功沒有。如果現實了 progressBar 的話就表示成功了。
4、處理進度條 UI 和文字內容,render部分
/** * @desc 處理 progressNumber */const validProgress = (progress: number | undefined) => { //當你的參數定義了 number 等類型,你必須對 !progress 的時候處理,不然 ts 會提示你錯誤。 if (!progress || progress < 0) { return 0; } else if (progress > 100) { return 100; } return progress;};/** * @desc 除法處理成0-100的整數 * @param step * @param total */const percentDeal = (step: number | undefined, total: number | undefined) => { if (!step || !total) { return 0; } return (step / total) * 100;};/** * @param text 百分比顯示 */const parseIntPrecent = (text: number): string => `${Math.ceil(text)}%`;class ProgressBar extends Component<IProgressProps> { /* ... ....defaultProps .....propTypes ...... */ render(){ // 把需要的值先從 this.props 中取出來 // restProps 擴充參數用 const { prefixCls, step, total, showInfo, color, ...restProps } = this.props; /** * percent 百分比 * text tip 顯示文字 * progressInfo 提示模塊 * porgress 主模塊 */ let percent; let text; let progressInfo; let progress; //處理百分比顯示內容 percent = percentDeal(step, total); text = parseIntPrecent(validProgress(percent)); // 如果 true 的話,我們使用創(chuàng)建一個 showInfo 模塊 if (showInfo) { progressInfo = ( <div className={`${prefixCls}-show-info`}> <span className={`${prefixCls}-text`}>{text}</span> </div> ); } //創(chuàng)建一個主模塊用做進度條 //prefixCls 這里統一了命名 progress = ( <div> <div className={`${prefixCls}-outer`}> <div className={`${prefixCls}-inner`}> <div className={`${prefixCls}-bg`}> {progressInfo || null} </div> </div> </div> </div> ); return ( <div {...restProps} className={`${prefixCls}`}> {progress} </div> ); }}復制代碼要點:把處理數據的函數定義在 class 外部,不要在 render 中處理數據。 進度條的實現很多種,這里就是普通的三層,文字,背景,進度條,和外層。
style.less5、根據上面的 gif 設計圖來實現一下樣式
.tiger-progress { &-outer { width: 100%; display: inline-block; margin-top:30px; margin-right: 0; padding-right: 0; } &-inner { vertical-align: middle; display: inline-block; background: #eeeeee; border-radius: 100px; position: relative; width: 100%; }//預留 &-bg 背景顏色代表進度條的長度,灰色的 inner 背景 &-line { width: 100%; font-size: inherit; position: relative; } &-text { word-break: normal; width: 2em; text-align: left; font-size: 1em; margin-left: 8px; vertical-align: middle; display: inline-block; white-space: nowrap; line-height: 1; }}復制代碼要點:// &-bg 顏色代表進度條的長度,灰色的 &-inner 背景作為總的長度。
補充 render 內的代碼, 根據輸入的 step 和 total 計算出來的數據來設置一下進度條的長度。
const { prefixCls, step, total, showInfo, color, ...restProps } = this.props; /** * percent 百分比 * text tip 顯示文字 * progressInfo 提示模塊 * porgress 主模塊 */let percent;let text;let progressInfo;let progress;percent = percentDeal(step, total);console..log("percent",percent)// percent: 20text = parseIntPrecent(validProgress(percent));console.log('text',text)// text: 20%if (showInfo) { progressInfo = ( <div className={`${prefixCls}-show-info`}> <span className={`${prefixCls}-text`}>{text}</span> </div> );}// color defalutProps 定義默認的顏色// 前面&-bg 設置 relative 定位const fixBgStyle = { width: text, height: "12px", background: color, borderRadius: "100px"};progress = ( <div> <div className={`${prefixCls}-outer`}> <div className={`${prefixCls}-inner`}> <div className={`${prefixCls}-bg`} style={fixBgStyle}> {progressInfo || null} </div> </div> </div> </div>);return ( <div {...restProps} className="tiger-progress"> {progress} </div>);復制代碼大功告成是不是很簡單,然我們再來看看效果codesandbox.io/s/940nq3531… ,調試一下代碼
作者:黑馬程序員大數據培訓學院
首發(fā):http://web.itheima.com/