react: 不一样的 ant design

806 阅读2分钟

树形控件: Tree

与后端数据的斗智斗勇

ant给出的树形控件接口如下

const treeData = [
  {
    title: 'parent 1',
    key: '0-0',
    children: [
      {
        title: 'parent 1-0',
        key: '0-0-0',
        disabled: true,
        children: [
          {
            title: 'leaf',
            key: '0-0-0-0',
            disableCheckbox: true,
          }
       ],
     },
     {
       title: 'parent 1-1',
       key: '0-0-1'
     },
   ],
 },
];

后端给出的接口如下

const treeData = [
  {
    name: 'parent 1',
    id: '0-0',
    subs: [
      {
        name: 'parent 1-0',
        id: '0-0-0',
        subs: [
          {
            name: 'leaf',
            id: '0-0-0-0'
          }
       ],
     },
     {
       name: 'parent 1-1',
       id: '0-0-1'
     },
   ],
 },
];

转换函数如下, 其他无需转换的属性可以使用ant给出的

public transferData(data: IWorkData[]) {
  data.forEach((item: IWorkData) => {
    item.key = item.id;
    item.children = item.subsets;
    item.title = item.name
    // 递归
    if (item.subs && item.subs.length > 0) {
       this.transferData(item.subs);
    }});

   return data;
}

实现不一样的 UI 界面

image.png

我们都知道ant的树形结构是很单纯的树形接口, title为纯文字, 那如果我想实现, 在每个节点后面都有一个tag标签怎么办, 这个时候需要对 title进行改造, 取每个需要展示的节点, 循环节点操作

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import { Tree, Tag } from "antd";
import "./index.css";
const treeData = [
  {
    name: "parent 1",
    id: "0-0",
    role: '',
    subs: [
      {
        name: "parent 1-0",
        id: "0-0-0",
        role: '',
        subs: [
          {
            name: "leaf232",
            id: "0-0-0-0",
            role: '测试人员',
          },
          {
            name: "leaf",
            id: "0-0-0-1",
            role: '',
          }
        ]
      }
    ]
  }
];

const a = (data) => {
  data.forEach((item) => {
    item.key = item.id;
    item.children = item.subs;
    item.title = (
    <div>
        <span>{ item.name }</span>
        {item.role && <Tag>{ item.role }</Tag>}
    </div>)
    if(item.subs && item.subs.length > 0) {
      a(item.subs)
    }
  });

  return data;
};

const Demo = () => {

  return (
    <Tree
      checkable
      defaultCheckedKeys={["0-0-0", "0-0-1"]}
      treeData={a(treeData)}
    />
  );
};

ReactDOM.render(<Demo />, document.getElementById("container"));

效果图

image.png

选择器: Select

实现效果1

要实现的UI 效果图如下, 单选, 选中后 需要在选项后面出现一个小对钩

image.png

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Select } from "antd";
import { CheckOutlined } from "@ant-design/icons";

const options = [
  { id: "1", name: "面包" },
  { id: "2", name: "香蕉" },
  { id: "3", name: "苹果" },
  { id: "4", name: "蛋糕" }
];
const value = "1";
const { Option } = Select;
ReactDOM.render(
  <Select
    showArrow
    value={value}
    optionLabelProp="label"
    onChange={(value) => console.log(value)}
    style={{ width: "200px" }}
  >
    {options.map((type) => {
      return (
        <Option value={type.id} label={type.name}>
          <div className="label-item">
            {type.name}
            {value === type.id && <CheckOutlined />}
          </div>
        </Option>
      );
    })}
  </Select>,
  document.getElementById("container")
);

// css样式
.label-item {
  display: flex;
  justify-content: space-between;
}

表格: Table

实现效果, 自定义空数据显示

ant design提供的属性可以设置空数据文案, 但是通常我们都是文案与图标一起, 或者有其他元素,这个时候就不可以使用 locale 属性.

image.png

不过, antd 还提供了另一个组件ConfigProvider, 为组件提供统一的全局化配置。

import { ConfigProvider } from 'antd';

//空的数据
const customizeRenderEmpty = () => (
    //这里面就是我们自己定义的空状态
    <div style={{ textAlign: 'center' }}>
        <img src={emptyIcon} />
        <p>{intl.get('holidayNone')}</p>
    </div>
);

<ConfigProvider renderEmpty={customizeRenderEmpty}>
    <Table
        dataSource={holiday}
        columns={columns}
        loading={showLoading}
        pagination={{
            hideOnSinglePage: true,
            pageSize: pagination.take,
            total: pagination.size,
            onChange: (e: number) => this.changePage(e),
        }}
    />
</ConfigProvider>

做一个完全受控的 DatePicker

之所以诞生做一个完全受控的思想来自于, 这个 DatePicker, 不止能在该组件内部清空数据, 组件职位也有一个重置的按钮. 项目 使用ts, 所以传入的必须符合 参数类型.

按照正常操作, 我们应该是给RangePicker绑定一个value, 然后点击清空的时候赋值为 空那个字符串.