欢迎访问宙启技术站
智能推送

React-View-UI组件库封装Loading加载中源码

发布时间:2023-05-14 08:46:35

在 React-View-UI 组件库中,有一个 Loading 组件,可以用于页面加载中或者数据处理时的 Loading 效果,方便用户对页面的状态进行更直观的了解。下面我们来看一下这个 Loading 组件的封装源码。

首先,我们需要对该组件进行一个初步的设计,思考它所需要的 props,功能,以及样式等方面。在这里,我们确定了以下几个方面:

#### props

- show: Boolean, 是否展示 Loading 组件;

- size: String, Loading 组件的大小,支持 'small', 'default', 'large' 三种;

- color: String, Loading 组件的颜色,支持十六进制和 rgb;

- text: String, Loading 组件展示的文字,可为空。

#### 功能

- 支持展示 Loading 组件;

- 支持 Loading 组件的大小、颜色以及文字的设置;

- 展示 Loading 组件时,页面不可进行其他的操作。

#### 样式

- 展示效果为一个圆形的 Loading 效果;

- Loading 组件默认宽高为 1em;

- Loading 组件的颜色、大小、以及文字样式等可以由用户进行自主设置。

有了上述的设计思路,我们之后的工作就是进行代码实现。我们首先在 src/components 目录下创建了一个 loading 目录,用于存放 Loading 组件的相关代码。在该目录下,我们首先新建了一个 loading.tsx 文件,负责组件内部的逻辑和渲染。

loading.tsx 文件中,我们首先导入所需要的库和组件,代码如下:

import React from 'react';
import classNames from 'classnames';
import { Icon } from '../icon';
import './style/index.less';

其中,classnames 库的作用是帮助我们在组件中方便地进行 CSS 类名的拼接,而 Icon 组件则用于展示 Loading 的图标,比较简单就不在这里赘述了。

接下来,我们定义了 LoadingProps 的类型,包括了我们上述列举的几个 props,代码如下:

interface LoadingProps {
  show?: boolean;
  size?: 'small' | 'default' | 'large';
  color?: string;
  text?: string;
}

可以看到,我们使用了 interface 关键字定义了一个接口,用于规范我们组件所需要的 props。其中,show 用于控制 Loading 组件的展示与隐藏,size 可以确定 Loading 组件的大小,color 可以设置 Loading 组件的颜色,而 text 则控制 Loading 组件下方的文字。在这里,我们使用了 ? 对所有 props 进行了可选设置,这是为了让组件更加灵活,用户可以选择性地传入这些 props。

接下来,我们对 Loading 组件进行函数式组件的定义,代码如下:

const Loading: React.FC<LoadingProps> = ({
  show = true,
  size = 'default',
  color = '#000000',
  text = '',
}) => {
  return (
    show && (
      <div
        className={classNames('rv-loading', {
          [rv-loading-${size}]: true,
        })}
      >
        <Icon type="loading" color={color} />
        {text && <span className="rv-loading__text">{text}</span>}
      </div>
    )
  );
};

可以看到,在 Loading 组件的渲染中,我们首先根据 show 属性决定是否展示 Loading 组件,若为 true,则展示 Loading 组件,否则什么都不渲染。接下来,我们在 div 标签中使用了 classNames 库生成了一个包含了对应 class 名称的字符串,进而控制组件宽高及展示的效果。其中,我们使用了 size 作为后缀,比如当 size 为 'small' 时,我们会生成一个样式为 rv-loading-small 的字符串,用于控制组件的大小。

另外,我们在 div 标签内部添加了 Icon 组件,用于展示 Loading 效果,而 text 则通过一个 span 标签进行添加,用于展示组件下方的文字。

最后,我们还要在组件目录中新建一个 style/index.less 文件,用于编写 Loading 组件的样式,具体代码如下:

.rv-loading {
  display: inline-flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: center;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.5);
  z-index: 99999;

  // 小尺寸 Loading 样式
  &.rv-loading-small {
    width: 1em;
    height: 1em;

    .rv-icon {
      font-size: 0.5em;
    }
  }

  // 中等尺寸 Loading 样式
  &.rv-loading-default {
    width: 1em;
    height: 1em;
  }

  // 大尺寸 Loading 样式
  &.rv-loading-large {
    width: 2em;
    height: 2em;

    .rv-icon {
      font-size: 1em;
    }
  }

  .rv-icon {
    animation: rv-loading-rotate 0.8s linear infinite;
  }

  @keyframes rv-loading-rotate {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
  }

  &.__notext {
    .rv-icon {
      margin-bottom: 0;
    }
  }

  &.__textOnly {
    .rv-icon {
      margin-bottom: 0;
    }
  }

  &.vertical {
    .rv-icon {
      margin-right: 0;
      margin-bottom: 8px;
    }
  }
  
  .rv-loading__text {
    display: block;
    margin-top: 8px;
    color: rgba(0, 0, 0, 0.85);
    font-size: 12px;
    line-height: 20px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: center;
  }
}

其中,我们通过 flex 布局使组件保持居中,同时添加了一个白色半透明的蒙层,使得组件展示时页面不可进行其他操作。

接下来,我们对 rv-loading 类名进行了样式的设置,支持了三种大小的 Loading 组件。在这里,我们使用了一个动画,用于控制 Loading 图标的旋转效果。

另外,我们还针对组件的文本进行了样式的设置,主要用于支持 Text Only 以及不带 Text 的两种模式。

最后,Loading 组件就制作完成了,在使用的时候,我们只需要调用 Loading 组件即可,比如:

import React, { useState, useEffect } from 'react';
import { Loading } from 'rv-view';

export default () => {
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    setIsLoading(true);

    setTimeout(() => {
      setIsLoading(false);
    }, 2000);
  }, []);

  return (
    <div>
      <div
        style={{
          height: 500,
          background: '#f0f0f0',
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
        }}
      >
        <div>这里是页面内容</div>
      </div>
      <Loading show={isLoading} text="Loading..." />
    </div>
  );
};

在这个例子中,我们使用了 useState 和 useEffect 两个 Hooks,用于控制 Loading 组件的展示。具体来说,我们初始化了 isLoading 的状态为 false,表示不展示 Loading 组件。在 useEffect 钩子中,我们设置了 isLoading 为 true,以模拟