改造antd Spin,实现方法调用出现全局加载遮罩

2,228 阅读1分钟

封装 Spin 组件,可以跟 Modal.method() 一样,调用静态方法,实现全局加载遮罩。

实现前台请求相关处理逻辑过于复杂时,加载状态传递困难的问题。

实现代码

import React from 'react';
import ReactDOM from 'react-dom';
import { Spin } from 'antd';
import 'antd/dist/reset.css';

/** 样式 */
const style = {
  loadingContainer: {
    position'fixed',
    top0,
    left0,
    right0,
    bottom0,
    zIndex9999,
    display'none',
  },
  LoadingMask: {
    position'absolute',
    top0,
    left0,
    right0,
    bottom0,
    zIndex9999,
    display'flex',
    justifyContent'center',
    alignItems'center',
    backgroundColor'#ffffffb3',
  }
}

/** 默认的一些自定义配置,如设置过全局config可忽略 */
const defaultConfig = {
  tip'加载中……',
  size'large',
}

/** 全局遮罩,提供方法调用实现视口遮罩 */
function globalLoadingMask() {
  if (!document.getElementById('loading-container')) {
    const loadingContainer = document.createElement('div');
    loadingContainer.id = 'loading-container';
    loadingContainer.style = 'display: none;';
    for (const key in style.loadingContainer) {
      loadingContainer.style[key] = style.loadingContainer[key]
    }
    document.body.appendChild(loadingContainer);
  }
  const loadingContainer = document.getElementById('loading-container')

  /** 渲染方法 */
  function render(config = {}) {
    const { zIndex, tip, size, ...resetProps } = { ...defaultConfig, ...config };
    // 允许自定义zIndex,避免多层弹窗场景下出现误遮罩以及未遮罩问题
    if (zIndex) loadingContainer.style.zIndex = zIndex;
    ReactDOM.render(
      <div style={style.LoadingMask}>
        <Spin size={size} {...resetProps} />
      </div>,
      loadingContainer
    )
  }

  /** 出现遮罩 */
  function show(defaultConfig = {}) {
    loadingContainer.style.display = 'block';
    render(defaultConfig)
  }
  /** 隐藏遮罩 */
  function hide() {
    loadingContainer.style.style = 'none';
    ReactDOM.unmountComponentAtNode(loadingContainer);
  }
  /** 更新遮罩配置 */
  function update(newConfig = {}) {
    render(newConfig)
  }

  return {
    show,
    hide,
    update
  }
};

/** 使用Spin即注入所需API配置 */
function PackingSpin(props = {}) {
  return <Spin {...defaultConfig} {...propskey={props.spinning}>{props.children}</Spin>
}

/** 挂载静态方法 */
let loadingFunc = globalLoadingMask();
for (const key in loadingFunc) {
  PackingSpin[key] = loadingFunc[key]
}

export default PackingSpin;

使用

import React from 'react'
import SpinFunc from './SpinFunc';
import { Table } from 'antd';

export default function App() {

  return (
    <div>
      {/* 标签使用 */}
      <SpinFunc>
        <Table />
      </SpinFunc>

      <button onClick={() => {
        // 方法使用
        SpinFunc.show({ zIndex: 10 })// 可以传参修改配置
        setTimeout(() => {
          SpinFunc.hide()
        }, 1000);
      }}>loading</button>
    </div>
  )
}


效果

Spin组件全局遮罩实现效果