react antd EditableProTable - 可编辑表格

与编辑表格外的内容联动
value	同 dataSource,传入一个数组,是 table 渲染的元数据	T[]	undefined
onChange	dataSource 修改时触发,删除和修改都会触发,如果设置了 value,Table 会成为一个受控组件。	(value:T[])=>void	undefined
recordCreatorProps	新建一行数据的相关配置	RecordCreatorProps & ButtonProps	-
maxLength	最大的行数,到达最大行数新建按钮会自动消失	number	-
editable	可编辑表格的相关配置	TableRowEditable	-
controlled	是否受控, 如果受控每次编辑都会触发 onChange,并且会修改 dataSource	boolean	false
editableFormRef	table 所有的 form,带了一些表格特有的操作	React.Ref<EditableFormInstance<T>>	undefined

在这里插入图片描述

import type {
   
  ActionType,
  EditableFormInstance,
  ProColumns,
  ProFormInstance,
} from '@ant-design/pro-components';
import {
   
  EditableProTable,
  ProCard,
  ProForm,
  ProFormDependency,
  ProFormDigit,
} from '@ant-design/pro-components';
import React, {
    useRef, useState } from 'react';

type DataSourceType = {
   
  id: React.Key;
  associate?: string;
  questionsNum?: number;
  type?: string;
  fraction?: number;
  scoringMethod?: string;
};

const defaultData: DataSourceType[] = [
  {
   
    id: 624748504,
    associate: '题库名称一',
    questionsNum: 10,
    type: 'multiple',
    scoringMethod: 'continuous',
    fraction: 20,
  },
  {
   
    id: 624691229,
    associate: '题库名称二',
    questionsNum: 10,
    scoringMethod: 'continuous',
    type: 'radio',
    fraction: 20,
  },
  {
   
    id: 624748503,
    associate: '题库名称三',
    questionsNum: 10,
    type: 'judge',
    scoringMethod: 'continuous',
    fraction: 20,
  },
  {
   
    id: 624691220,
    associate: '题库名称四',
    questionsNum: 10,
    scoringMethod: 'continuous',
    type: 'vacant',
    fraction: 20,
  },
];

export default () => {
   
  const [editableKeys, setEditableRowKeys] = useState<React.Key[]>(() => []);
  const formRef = useRef<ProFormInstance<any>>();
  const actionRef = useRef<ActionType>();
  const editableFormRef = useRef<EditableFormInstance>();
  const columns: ProColumns<DataSourceType>[] = [
    {
   
      title: '关联题库',
      dataIndex: 'associate',
      valueType: 'text',
      ellipsis: true,
    },
    {
   
      title: '题型',
      key: 'type',
      dataIndex: 'type',
      valueType: 'select',
      valueEnum: {
   
        multiple: {
    text: '多选题', status: 'Default' },
        radio: {
    text: '单选题', status: 'Warning' },
        vacant: {
   
          text: '填空题',
          status: 'Error',
        },
        judge: {
   
          text: '判断题',
          status: 'Success',
        },
      },
    },
    {
   
      title: '题数',
      dataIndex: 'questionsNum',
      valueType: 'digit',
    },
    {
   
      title: '计分方式',
      dataIndex: 'scoringMethod',
      valueType: 'select',
      request: async () => [
        {
   
          value: 'discrete',
          label: '离散型',
        },
        {
   
          value: 'continuous',
          label: '连续型',
        },
      ],
      fieldProps: (_, {
    rowIndex }) => {
   
        return {
   
          onSelect: () => {
   
            // 每次选中重置参数
            editableFormRef.current?.setRowData?.(rowIndex, {
    fraction: [] });
          },
        };
      },
    },
    {
   
      title: '分值',
      width: 150,
      dataIndex: 'fraction',
      valueType: (record) => {
   
        const scoringMethod = record?.scoringMethod;
        if (scoringMethod === 'discrete') return 'select';
        return 'digit';
      },
      fieldProps: {
   
        mode: 'multiple',
      },
      request: async () =>
        ['A', 'B', 'D', 'E', 'F'].map((item, index) => ({
   
          label: item,
          value: index,
        })),
    },
    {
   
      title: '操作',
      valueType: 'option',
      render: (_, row) => [
        <a
          key="delete"
          onClick={
   () => {
   
            const tableDataSource = formRef.current?.getFieldValue(
              'table',
            ) as DataSourceType[];
            formRef.current?.setFieldsValue({
   
              table: tableDataSource.filter((item) => item.id !== row?.id),
            });
          }}
        >
          移除
        </a>,
        <a
          key="edit"
          onClick={
   () => {
   
            actionRef.current?.startEditable(row.id);
          }}
        >
          编辑
        </a>,
      ],
    },
  ];

  return (
    <ProCard>
      <div
        style={
   {
   
          maxWidth: 800,
          margin: 'auto',
        }}
      >
        <ProForm<{
   
          table: DataSourceType[];
        }>
          formRef={
   formRef}
          initialValues={
   {
   
            table: defaultData,
          }}
        >
          <ProFormDependency name={
   ['table']}>
            {
   ({
    table }) => {
   
              const info = (table as DataSourceType[]).reduce(
                (pre, item) => {
   
                  return {
   
                    totalScore:
                      pre.totalScore +
                      parseInt((item?.fraction || 0).toString(), 10),
                    questions:
                      pre.questions +
                      parseInt((item?.questionsNum || 0).toString(), 10),
                  };
                },
                {
    totalScore: 0, questions: 0 },
              );
              return (
                <div
                  style={
   {
   
                    display: 'flex',
                    alignItems: 'center',
                    gap: 16,
                    paddingBlockEnd: 16,
                  }}
                >
                  <div style={
   {
    flex: 1 }}>总分:{
   info.totalScore}</div>
                  <div style={
   {
    flex: 1 }}>题数:{
   info.questions}</div>
                  <div style={
   {
    flex: 2 }}>
                    <ProFormDigit label="及格分" />
                  </div>
                  <div style={
   {
    flex: 2 }}>
                    <ProFormDigit label="考试时间(分钟)" />
                  </div>
                </div>
              );
            }}
          </ProFormDependency>
          <EditableProTable<DataSourceType>
            rowKey="id"
            scroll={
   {
   
              x: true,
            }}
            editableFormRef={
   editableFormRef}
            controlled
            actionRef={
   actionRef}
            formItemProps={
   {
   
              label: '题库编辑',
              rules: [
                {
   
                  validator: async (_, value) => {
   
                    if (value.length < 1) {
   
                      throw new Error('请至少添加一个题库');
                    }

                    if (value.length > 5) {
   
                      throw new Error('最多可以设置五个题库');
                    }
                  },
                },
              ],
            }}
            maxLength={
   10}
            name="table"
            columns={
   columns}
            recordCreatorProps={
   {
   
              record: (index) => {
   
                return {
    id: index + 1 };
              },
            }}
            editable={
   {
   
              type: 'multiple',
              editableKeys,
              onChange: setEditableRowKeys,
            }}
          />
        </ProForm>
      </div>
    </ProCard>
  );
};

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-01-09 19:08:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-09 19:08:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-09 19:08:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-09 19:08:01       18 阅读

热门阅读

  1. 智能寻迹避障清障机器人设计(摘 要)

    2024-01-09 19:08:01       40 阅读
  2. 布隆过滤器的原理

    2024-01-09 19:08:01       24 阅读
  3. 编程笔记 html5&css&js 025 HTML输入类型(1/2)

    2024-01-09 19:08:01       36 阅读
  4. Qt隐式共享浅析

    2024-01-09 19:08:01       34 阅读
  5. 【前端】JQuery(学习笔记)

    2024-01-09 19:08:01       32 阅读
  6. 【CSS】讲一讲BFC、IFC、GFC、FFC

    2024-01-09 19:08:01       40 阅读