更新時(shí)間:2018-11-16 來源:黑馬程序員技術(shù)社區(qū) 瀏覽量:
TypeScript 入門,寫一個(gè) react 進(jìn)度條組件寫在最前面如果你寫過 react 的組件, 這篇文章對(duì)與你來說基本沒有什么難度。純粹的是加上了一點(diǎn) ts 的知識(shí)。我完全是以學(xué)習(xí)者的姿態(tài)來描述我寫組件的過程,很多不嚴(yán)謹(jǐn)?shù)牡胤秸?qǐng)大家指出來哈哈。
看看實(shí)現(xiàn)的效果-gif 動(dòng)圖效果
這是一個(gè)普通的 UI 組件,難點(diǎn)主要在設(shè)計(jì)(css)上面。
需求:分步驟進(jìn)行的一個(gè)精度條,我們只需要輸入?yún)?shù),step 和 total 來計(jì)算出百分比然后顯示就 ok 了。
/** @param step 第幾步* @param total 總共的步驟* @param showInfo 是否需要顯示百分比提示* @param color 可以自定義顏色*/復(fù)制代碼說了這么多開始動(dòng)手吧環(huán)境配置方面就略過了,這里我們直接來寫代碼
需要配置 node,ts,less 環(huán)境
1、在你的 componments 文件下創(chuàng)建一個(gè) progressBar 文件夾。tsx 是 react下特殊 ts 文件。 然后在 progressBar 下面繼續(xù)添加 index.tsx 和 style.less
-- componments -- progressBar -- index.tsx -- style.less復(fù)制代碼index.tsx2、先引進(jìn)必須的組件
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;復(fù)制代碼要點(diǎn): IProgressProps ,使用 pascal 命名,用 I打頭,Props 是代表這個(gè)接口參數(shù)支持。
3、根據(jù)我們上面需求的分析,我們來定義 interface,定義類的 propTypes 和 defalutProps
export interface IProgressProps { // prefixCls 為了以后樣式統(tǒng)一設(shè)置的 classname prefixCls?: string; step?: number; total?: number; showInfo?: boolean; color?: string;}class ProgressBar extends Component<IProgressProps> { //設(shè)置默認(rèn)值 static defaultProps = { prefixCls: 'demo-progress', step: 2, total: 10, showInfo: false, color: '#FFE103' }; //設(shè)置類的參數(shù)類型 static propTypes = { prefixCls:PropTypes.string, step: PropTypes.number, total: PropTypes.number, showInfo: PropTypes.bool, color: PropTypes.string }; render(){ return( <div>progressBar</div> ) }}復(fù)制代碼要點(diǎn): 其中的“ ?”表示可選,number 就是接口參數(shù)的類型。表示你輸入的必須是一個(gè) number 類型,不然 ts 會(huì)報(bào)錯(cuò)。這里我們可以引用一下 progressBar 模塊,看看成功沒有。如果現(xiàn)實(shí)了 progressBar 的話就表示成功了。
4、處理進(jìn)度條 UI 和文字內(nèi)容,render部分
/** * @desc 處理 progressNumber */const validProgress = (progress: number | undefined) => { //當(dāng)你的參數(shù)定義了 number 等類型,你必須對(duì) !progress 的時(shí)候處理,不然 ts 會(huì)提示你錯(cuò)誤。 if (!progress || progress < 0) { return 0; } else if (progress > 100) { return 100; } return progress;};/** * @desc 除法處理成0-100的整數(shù) * @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 擴(kuò)充參數(shù)用 const { prefixCls, step, total, showInfo, color, ...restProps } = this.props; /** * percent 百分比 * text tip 顯示文字 * progressInfo 提示模塊 * porgress 主模塊 */ let percent; let text; let progressInfo; let progress; //處理百分比顯示內(nèi)容 percent = percentDeal(step, total); text = parseIntPrecent(validProgress(percent)); // 如果 true 的話,我們使用創(chuàng)建一個(gè) showInfo 模塊 if (showInfo) { progressInfo = ( <div className={`${prefixCls}-show-info`}> <span className={`${prefixCls}-text`}>{text}</span> </div> ); } //創(chuàng)建一個(gè)主模塊用做進(jìn)度條 //prefixCls 這里統(tǒng)一了命名 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> ); }}復(fù)制代碼要點(diǎn):把處理數(shù)據(jù)的函數(shù)定義在 class 外部,不要在 render 中處理數(shù)據(jù)。 進(jìn)度條的實(shí)現(xiàn)很多種,這里就是普通的三層,文字,背景,進(jìn)度條,和外層。
style.less5、根據(jù)上面的 gif 設(shè)計(jì)圖來實(shí)現(xiàn)一下樣式
.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%; }//預(yù)留 &-bg 背景顏色代表進(jìn)度條的長(zhǎng)度,灰色的 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; }}復(fù)制代碼要點(diǎn):// &-bg 顏色代表進(jìn)度條的長(zhǎng)度,灰色的 &-inner 背景作為總的長(zhǎng)度。
補(bǔ)充 render 內(nèi)的代碼, 根據(jù)輸入的 step 和 total 計(jì)算出來的數(shù)據(jù)來設(shè)置一下進(jìn)度條的長(zhǎng)度。
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 定義默認(rèn)的顏色// 前面&-bg 設(shè)置 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>);復(fù)制代碼大功告成是不是很簡(jiǎn)單,然我們?cè)賮砜纯葱Ч鹀odesandbox.io/s/940nq3531… ,調(diào)試一下代碼
作者:黑馬程序員大數(shù)據(jù)培訓(xùn)學(xué)院
首發(fā):http://web.itheima.com/