react+antd使用过程中总结的一些组件

显示loading–mySpin

如何使用
{mySpin({ spinning: checking, tip: "校验中" })}
/**
 * @param params.spinning 是否显示loading
 * @param params.tip 提示文字,默认加载中
 * @description 需要父盒子使用相对定位position:relative
 */
export function mySpin(params) {
  const { spinning = false, tip = "加载中..." } = params;
  if (!spinning) return "";
  return (
    <div
      style={{
        position: "absolute",
        width: "100%",
        height: "100%",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        zIndex: 999,
        background: "rgba(255,255,255,0.5)",
      }}
    >
      <Spin tip={tip} spinning={spinning} />
    </div>
  );
}

下载文件–文件流–exportFile

使用情况是只需要传下载文件的url,入参就可以把文件下载下来,文件名是后端的
/** 文件流保存文件 文件名由后端提供*/
export async function exportFile(params, total = 1000) {
  const { url, payload, fileName = "未命名", time = 10 } = params;
  addLoading("正在下载文件,请稍后...");
  request(
    url,
    { ...payload },
    (res) => {
      const { data, headers } = res;
      let blob = new Blob([res.data]);
      if (headers["content-disposition"] || fileName) {
        let name = headers["content-disposition"] ? headers["content-disposition"].replace(
          /attachment;filename=/,
          ""
        ) : fileName;
        name = decodeURIComponent(name) || fileName;
        saveAs(blob, name);
      } else if(size>0){
        saveAs(blob, fileName);
      } else {
        let reader = new FileReader();
        reader.readAsText(data, "utf-8");
        reader.onload = function () {
          let data1 = JSON.parse(reader.result);
          message.warning(data1.message);
        };
        // message.warning("文件下载失败!");
      }
    },
    (err) => {
      removeLoading();
      message.warning(err.message || "下载失败!");
    },
    true
  );
}

通用表格 comTable

在and表格的基础上进行扩展
/*
 * @Autor: xiangr
 * @Date: 2021-04-07 11:42:28
 * @LastEditors: xiangr
 * @LastEditTime: 2021-05-18 15:46:01
 */
import React, { useState, useEffect } from "react";
import { TableProps as RcTableProps } from "rc-table/lib/Table";
import { Button, Modal, message, Table } from "antd";
import ComPagination from "./comPaginationX";
import "../../style/comTable.scss";
import { throttling } from "../../util/x_util";
interface tableProps extends RcTableProps {
  dropdownPrefixCls?: string;
  dataSource?: Array<any>;
  columns?: any;
  pagination?:
    | false
    | {
        pageSize?: number;
        current?: number;
        total?: number;
        pageChange?: (pageNum: number, pageSize: number) => void;
        sizeChange?: (pageNum: number, pageSize: number) => void;
      };
  loading?: boolean;
  size?: "small" | "middle" | "large" | undefined;
  bordered?: boolean;
  locale?: object;
  onChange?: (pagination: any, filters: any, sorter: any, extra: any) => void;
  rowSelection?: any;
  getPopupContainer?: any;
  scroll?: object;
  sortDirections?: any;
  showSorterTooltip?: any;
  className?: string;
  id?: string;
}
declare type ComTableProps = {
  /** antd table 的所有props */
  tableProps: tableProps;
  /** 额外的属性 */
  extraProps?: {
    // count?: boolean;
    /** 额外的DOM节点 */
    extraEl?: string;
    /** 页面有多个表格,表格直接的间隔 */
    tableSpacing?: number;
    /** 区分奇数行和偶数行 */
    distinguishRow?: boolean;
    /** 页面间距,默认30 */
    pageSpacing?: number;
    minHeight?: number;
  };
};
/**
 * @description 通用表格
 * @tips pageChange的方法需要在pagination里面
 */
export default function ComTable(props: ComTableProps) {
  const [tableHeight, setTableHeight] = useState(200);
  const {
    tableProps,
    extraProps = { distinguishRow: true, minHeight: 100, pageSpacing: 30 },
  } = props;
  const { pagination, dataSource, footer } = tableProps;
  /* 是否固定暂无数据 */
  const [fixedAntEmpty, setfixedAntEmpty] = useState(false);
  let pageSpacing: number = 30;
  if (extraProps.pageSpacing) {
    pageSpacing = extraProps.pageSpacing;
  }
  // let fixedAntEmpty = false;
  const comPaginationProps = {
    ...pagination,
    /** 分页的位置 left | right | center  */
    position: "right",
    id: (tableProps.id || tableProps.className || "") + "Pagination",
    pageChange: (pageNum: number, pageSize: number) => {
      // 如果loading为真,则不响应
      if (tableProps && !tableProps.loading) {
        if (
          pagination != false &&
          typeof pagination.pageChange === "function"
        ) {
          pagination.pageChange(pageNum, pageSize);
        }
      }
    },
    showSizeChanger: true,
    showQuickJumper: false,
    pageSizeOptions: ["20", "50", "100"],
  };

  async function getScrollY() {
    setTimeout(async () => {
      let paginationDiv = document.querySelector(
        getElementName("paginationDiv")
      ) as HTMLElement;
      let tfooterTbody = document.querySelector(
        getElementName("tfooterTbody")
      ) as HTMLElement;
      if (tfooterTbody) {
        if (!tfooterTbody.classList.toString().includes("heji"))
          tfooterTbody.classList.add("heji");
      }
      let elFooter = document.querySelector(
        getElementName("tfooter")
      ) as HTMLElement;
      let summary = document.querySelector(
        getElementName("summary")
      ) as HTMLElement;
      let elHeader = document.querySelector(
        getElementName("theader")
      ) as HTMLElement;
      let elBody4 = document.querySelector(
        getElementName("tbody")
      ) as HTMLElement;
      // 计算表格的高度
      if (elHeader) {
        let sHeight: number;
        sHeight =
          window.innerHeight -
          elHeader.getBoundingClientRect().top -
          elHeader.getBoundingClientRect().height;
        if (paginationDiv) {
          sHeight = sHeight - paginationDiv.getBoundingClientRect().height;
        }

        if (
          extraProps &&
          extraProps.extraEl &&
          document.querySelector(extraProps.extraEl)
        )
          sHeight =
            sHeight -
            document.querySelector(extraProps.extraEl).getBoundingClientRect()
              .height;
        // 页面间距
        sHeight = sHeight - pageSpacing;
        // 存在多个表格的时候,需要的间隔
        if (extraProps && extraProps.tableSpacing) {
          sHeight = sHeight - extraProps.tableSpacing;
        }
        if (elFooter) {
          sHeight = sHeight - elFooter.clientHeight;
        }
        /* 兼容antd的总结栏 */
        if (summary) {
          sHeight = sHeight - summary.clientHeight;
        }

        const prent = elHeader.parentNode.parentNode.parentNode as HTMLElement;
        /* 有横向滚动条,空数据应该固定在中间 */
        const f = elHeader.clientWidth > prent.clientWidth + 2;
        if (fixedAntEmpty != f) {
          setfixedAntEmpty(f);
        }
        /** 取消固定分页 2021年12月23日15:51:41修改 */
        // if (elBody4) {
        //   // 把横向滚动条,和分页固定在底部,排除合计
        //   if (paginationDiv && f) {
        //     elBody4.style.minHeight = sHeight + "px";
        //   }
        // }
        let min = extraProps.minHeight || 100;
        if (sHeight < min) {
          sHeight = min;
        }
        setTableHeight(sHeight);
        changeClassName();
      }

      const fixedEmpty = document.querySelector(
        ".fixed-ant-empty .ant-table-placeholder .ant-empty-normal"
      )! as HTMLElement;
      if (fixedEmpty && elBody4) {
        fixedEmpty.style.left = `${
          elBody4.clientWidth / 2 - 32 + elBody4.getBoundingClientRect().left
        }px`;
      }
    }, 100);
  }
  function changeClassName() {
    let paginationDiv = document.querySelector(
      getElementName("paginationDiv")
    ) as HTMLElement;
    let tfooterTbody = document.querySelector(
      getElementName("tfooterTbody")
    ) as HTMLElement;
    if (tfooterTbody) {
      if (!tfooterTbody.classList.toString().includes("heji"))
        tfooterTbody.classList.add("heji");
    }
    let elFooter = document.querySelector(
      getElementName("tfooter")
    ) as HTMLElement;
    let summary = document.querySelector(
      getElementName("summary")
    ) as HTMLElement;
    let elHeader = document.querySelector(
      getElementName("theader")
    ) as HTMLElement;
    let elBody4 = document.querySelector(
      getElementName("tbody")
    ) as HTMLElement;
    const prent = elHeader.parentNode.parentNode.parentNode as HTMLElement;
    /* 是否有横向滚动条 */
    const hasHorizontalScroll = elHeader.clientWidth > prent.clientWidth + 2;
    const hasVerticalScroll =
      (elBody4.children[0] as HTMLElement).clientHeight > elBody4.clientHeight;
    let container = document.querySelector(getElementName("container"));
    const hasFooter =
      elFooter != undefined && elFooter != null && elFooter.clientHeight > 0;
    // const hasPagination =
    //   paginationDiv != undefined &&
    //   paginationDiv != null &&
    //   paginationDiv.clientHeight > 0;
    const hasHidescrollBar = hasFooter && hasHorizontalScroll;
    if (hasHidescrollBar) {
      document.querySelector(getElementName("tbody")).scrollLeft = 1;
      document.querySelector(getElementName("tfooterTbody")).scrollLeft = 1;
    }
    updateName(container, "has-horizontal-scroll", hasHorizontalScroll);
    updateName(container, "has-vertical-scroll", hasVerticalScroll);
    updateName(container, "has-footer", hasFooter);
    // updateName(container, "has-pagination", hasPagination);
    updateName(elBody4, "has-hidescrollBar", hasHidescrollBar);
  }
  function updateName(element: Element, classNmae: string, flag: boolean) {
    if (element) {
      if (flag) {
        if (!element.classList.toString().includes(classNmae)) {
          element.classList.add(classNmae);
        }
      } else {
        element.classList.remove(classNmae);
      }
    }
  }
  /** 使footer的滚动条可以滑动table-body的内容 */
  function onScrollCapture(e: any) {
    let parentList = getParentTag(e.target);
    let isFooter =
      parentList?.filter((a: any) => a.className == "ant-table-footer").length >
      0;
    let tbody = document.querySelector(getElementName("tbody"));
    if (isFooter) {
      tbody.scrollLeft = e.target.scrollLeft;
    }
  }
  /**
   * getParentTag - 获取传入标签的所有父级标签
   *
   * @param  { HTMLElement } startTag 初始dom节点
   * @param  {Array} parentTagList 初始dom节点的所有父级节点
   * @return {type} 递归/初始dom节点的所有父级节点
   */
  function getParentTag(startTag: any, parentTagList = []) {
    // 传入标签是否是DOM对象
    if (!(startTag instanceof HTMLElement))
      return console.error("receive only HTMLElement");
    // 父级标签是否是body,是着停止返回集合,反之继续
    if ("BODY" !== startTag.parentElement.nodeName) {
      // 放入集合
      parentTagList.push(startTag.parentElement);
      // 再上一层寻找
      return getParentTag(startTag.parentElement, parentTagList);
    }
    // 返回集合,结束
    else return parentTagList;
  }

  function getElementName(name: string) {
    const defaultName = ".ant-table";
    const obj = {
      tbody: ".ant-table-body",
      theader: "table thead.ant-table-thead",
      tbodytbody: ".ant-table-body table .ant-table-tbody",
      tfooterTbody: ".ant-table-footer .ant-table-body",
      tfooter: ".ant-table-footer",
      summary: ".ant-table-summary",
      container: ".ant-table-container",
    };
    if (name === "paginationDiv") {
      return tableProps.id
        ? `#${tableProps.id}Pagination.comPagination`
        : tableProps.className
        ? `.${tableProps.className}.comPagination`
        : ".comPagination";
    }
    return tableProps.id
      ? `#${tableProps.id} ${obj[name]}`
      : tableProps.className
      ? `.${tableProps.className} ${obj[name]}`
      : `${defaultName} ${obj[name]}`;
  }

  useEffect(() => {
    getScrollY();
  }, [tableProps, extraProps]);
  useEffect(() => {
    getScrollY();
    window.addEventListener("resize", throttling(getScrollY, 1000));
    return () => {
      window.removeEventListener("resize", throttling(getScrollY, 1000));
    };
  }, []);

  let className = fixedAntEmpty
    ? `fixed-ant-empty ${tableProps.className || ""}`
    : `${tableProps.className || ""}`;
  return (
    <div className="comTable" onScrollCapture={onScrollCapture}>
      <Table
        scroll={{ y: tableHeight }}
        {...tableProps}
        footer={(dataSource || []).length ? footer : null}
        pagination={false}
        className={className}
        rowClassName={(row, index) => {
          if (!(extraProps && extraProps.distinguishRow)) {
            return "";
          }
          return index % 2 === 0 ? "evenrow" : "oddrow";
        }}
      />
      {pagination && dataSource.length ? (
        <ComPagination {...comPaginationProps} />
      ) : (
        ""
      )}
    </div>
  );
}

  • 如何使用

react+antd使用过程中总结的一些组件_第1张图片

你可能感兴趣的:(hooks,js,react.js,javascript,前端)