首页技术文章正文

Typescript与ts结合应用

更新时间:2018-11-16 来源:黑马程序员技术社区 浏览量:

TypeScript 入门,写一个 react 进度条组件写在最前面如果你写过 react 的组件, 这篇文章对与你来说基本没有什么难度。纯粹的是加上了一点 ts 的知识。我完全是以学习者的姿态来描述我写组件的过程,很多不严谨的地方请大家指出来哈哈。
看看实现的效果-gif 动图效果    
1542357444159_166f2cdf3abbf0a4.gif

当然你可以点击这里亲自试一下效果,效果页面也可以打开下面 codeSandbox 看一下源代码(这玩意可能需要梯子)。

这是一个普通的 UI 组件,难点主要在设计(css)上面。
需求:分步骤进行的一个精度条,我们只需要输入参数,step 和 total 来计算出百分比然后显示就 ok 了。

/** @param step 第几步* @param total 总共的步骤* @param showInfo  是否需要显示百分比提示* @param color 可以自定义颜色*/复制代码说了这么多开始动手吧环境配置方面就略过了,这里我们直接来写代码
需要配置 node,ts,less 环境
1、在你的 componments 文件下创建一个 progressBar 文件夹。tsx 是 react下特殊 ts 文件。 然后在 progressBar 下面继续添加 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 的话,我们使用创建一个 showInfo 模块        if (showInfo) {            progressInfo = (                <div className={`${prefixCls}-show-info`}>                  <span className={`${prefixCls}-text`}>{text}</span>                </div>            );        }                //创建一个主模块用做进度条        //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… ,调试一下代码

作者:黑马程序员大数据培训学院
首发:http://web.itheima.com/

分享到:
在线咨询 我要报名
和我们在线交谈!