使用 Antd-UI 实现对表格的增删操作

在这里插入图片描述

Antd 是一个很优秀的组件库
在这里插入图片描述这篇文章使用 Antd 的 Model 组件和 Table 组件,实现对表格的增删操作。

首先来看一个基本的 Table 组件

import React from 'react'
import { Table } from 'antd'

// 数据源 ===> 一般都是从后端提供的接口中获取数据
const dataSource = [
  {
    key: '1',
    name: '胡彦斌',
    age: 32,
    address: '西湖区湖底公园1号',
  },
  {
    key: '2',
    name: '胡彦祖',
    age: 42,
    address: '西湖区湖底公园1号',
  },
];

// 展示在页面上的列数项,有几个对象,就有几列
const columns = [
  {
    title: '姓名',
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: '年龄',
    dataIndex: 'age',
    key: 'age',
  },
  {
    title: '住址',
    dataIndex: 'address',
    key: 'address',
  },
];

const City = () => {
  return (
    <Table dataSource={dataSource} columns={columns} />
  )
}

export default City

在这里插入图片描述

但是光有数据展示还不够,我们希望可以对数据进行点击选择操作

Table 组件上有一个 rowSelection 属性上的 onChange 事件,可以监听到每一次点击选择的表格项。

import React, { useState } from 'react'
import { Table } from 'antd';

// 数据源 ===> 一般都是从后端提供的接口中获取数据
const dataSource = [
  {
    key: '1',
    name: '胡彦斌',
    age: 32,
    address: '西湖区湖底公园1号',
  },
  {
    key: '2',
    name: '胡彦祖',
    age: 42,
    address: '西湖区湖底公园1号',
  },
];

// 展示在页面上的列数项,有几个对象,就有几列
const columns = [
  {
    title: '姓名',
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: '年龄',
    dataIndex: 'age',
    key: 'age',
  },
  {
    title: '住址',
    dataIndex: 'address',
    key: 'address',
  },
];

const rowSelection = {
  onChange: (selectedRowKeys, selectedRows) => {
    console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
  },
};

const City = () => {
  const [selectionType, setSelectionType] = useState('checkbox');

  return (
    <div>
      <Table
        rowSelection={{
          type: selectionType,
          ...rowSelection,
        }}
        columns={columns}
        dataSource={dataSource}
      />
    </div>
  );
}

export default City

在这里插入图片描述
得到了相对应的表格列表项之后,就可以请求后端的删除数据接口,对选中的数据进行删除。当然,删除数据是一项很危险的操作,我们有必要在真正删除之前提示操作者。

添加 Model 框提示,在操作者点击确认按钮时,进行真正的删除操作。

在这里插入图片描述

import React, { useState } from 'react'
import { Table, Modal } from 'antd';

const City = () => {
  const [selectionType, setSelectionType] = useState('checkbox');
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [selectedData, setSelectedData] = useState([])

  const showModal = () => {
    setIsModalVisible(true);
  };

  const handleOk = () => {
    console.log('selectedData', selectedData)
    // 获取数据,进行删除操作
    setIsModalVisible(false);
  };

  const handleCancel = () => {
    setIsModalVisible(false);
  };

  const rowSelection = {
    onChange: (selectedRowKeys, selectedRows) => {
      setSelectedData(selectedRows)
      showModal()
    },
  };

  return (
    <div>
      <Table
        rowSelection={{
          type: selectionType,
          ...rowSelection,
        }}
        columns={columns}
        dataSource={dataSource}
      />
      <Modal title="删除确认框" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
        <h1>确认是否删除?</h1>
      </Modal>
    </div>
  );
}

export default City

当数据过多时,需要进行分页操作。

PS:应该是我自身的问题,我不太清楚怎么通过 table 自带的分页去获取对应的页码数。所以我选择了使用 Antd 中 Pagination 组件

通过 Pagination 组件上的 onChange 事件,监听 pagination 的数字变化

在这里插入图片描述

import React, { useState, useEffect } from 'react'
import { Table, Modal, Pagination } from 'antd';

const City = () => {
  const [selectionType, setSelectionType] = useState('checkbox');
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [selectedData, setSelectedData] = useState([])
  const [pagination, setPagination] = useState(1)

  const showModal = () => {
    setIsModalVisible(true);
  };

  const handleOk = () => {
    console.log('selectedData', selectedData)
    // 获取数据,进行删除操作
    setIsModalVisible(false);
  };

  const handleCancel = () => {
    setIsModalVisible(false);
  };

  const rowSelection = {
    onChange: (selectedRowKeys, selectedRows) => {
      setSelectedData(selectedRows)
      showModal()
    },
  };

  const paginationChange = (pagination) => {
    console.log(pagination)
    setPagination(pagination)
  }

  useEffect(() => {
    // 请求函数
    requestList(pagination)
  }, [pagination])

  return (
    <div>
      <Table
        rowSelection={{
          type: selectionType,
          ...rowSelection,
        }}
        pagination={false}
        columns={columns}
        dataSource={dataSource}
      />
      <Pagination onChange={paginationChange} defaultCurrent={1} total={50} />
      <Modal title="删除确认框" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
        <h1>确认是否删除?</h1>
      </Modal>
    </div>
  );
}

export default City

到此一步,基本的数据展示与数据删除就可以了。

接下来添加按钮,用于实现 model 框的显示与隐藏,同时进行组件的封装,将添加信息的组件封装在一起。

import React, { useState, useEffect } from 'react'
import { Table, Modal, Pagination, Button, Form, Select, Input} from 'antd';

const City = () => {
  const [visible, setVisible] = useState(false)

  const handleClick = () => {
    setVisible(true)
  }

    const onCreate = (values) => {
    setVisible(false);
  }

  return (
    <div>
      <Button type="primary" onClick={handleClick}>添加信息</Button>
      <Table
        rowSelection={{
          type: selectionType,
          ...rowSelection,
        }}
        pagination={false}
        columns={columns}
        dataSource={dataSource}
      />
      <Pagination onChange={paginationChange} defaultCurrent={1} total={50} />
      <Modal title="删除确认框" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
        <h1>确认是否删除?</h1>
      </Modal>
      <Information
        visible={visible}
        onCreate={onCreate}
        onCancel={() => {
          setVisible(false);
        }}
      />
    </div>
  );
}

const Information = ({ visible, onCreate, onCancel }) => {
  const [form] = Form.useForm()
  return (
    <Modal
      visible={visible}
      okText="确认"
      cancelText="取消"
      onCancel={onCancel}
      onOk={() => {
        form
          .validateFields()
          .then((values) => {
            form.resetFields();
            onCreate(values);
          })
          .catch((info) => {
            console.log('Validate Failed:', info);
          });
      }}
    >
      <p>model</p>
    </Modal>
  )
}

export default City

在这里插入图片描述
model 框中填入 form 表单,model 框中的 onCreate 函数可以接收填写的内容。

// export default City
import React, { useState, useEffect } from 'react'
import { Table, Modal, Pagination, Button, Form, Select, Input } from 'antd';

const City = () => {
  const [visible, setVisible] = useState(false)

  const handleClick = () => {
    setVisible(true)
  }

  const onCreate = (values) => {
    console.log('onCreate', values)
    setVisible(false);
  }

  return (
    <div>
      <Button type="primary" onClick={handleClick}>添加信息</Button>
      <Table
        rowSelection={{
          type: selectionType,
          ...rowSelection,
        }}
        pagination={false}
        columns={columns}
        dataSource={dataSource}
      />
      <Pagination onChange={paginationChange} defaultCurrent={1} total={50} />
      <Modal title="删除确认框" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
        <h1>确认是否删除?</h1>
      </Modal>
      <Information
        visible={visible}
        onCreate={onCreate}
        onCancel={() => {
          setVisible(false);
        }}
      />
    </div>
  );
}

const Information = ({ visible, onCreate, onCancel }) => {
  const [form] = Form.useForm()
  return (
    <Modal
      visible={visible}
      okText="确认"
      cancelText="取消"
      onCancel={onCancel}
      onOk={() => {
        form
          .validateFields()
          .then((values) => {
            form.resetFields();
            onCreate(values);
          })
          .catch((info) => {
            console.log('Validate Failed:', info);
          });
      }}
    >
      <Form
        form={form}
        layout="vertical"
        name="form_in_modal"
        initialValues={{
          modifier: 'public',
        }}
      >
        <Form.Item
          name="id"
          label="选择城市"
          rules={[
            {
              required: true,
              message: '请选择',
            },
          ]}
        >
          <Select style={{ width: 100 }}>
            <Select.Option value={12443}>洛阳市</Select.Option>
            <Select.Option value={11443}>北京市</Select.Option>
          </Select>
        </Form.Item>
        <Form.Item
          name="franchisee_name"
          label="授权加盟商"
          rules={[
            {
              required: true,
              message: '请选择',
            },
          ]}
        >
          <Input type="text" placeholder="请输入姓名" />
        </Form.Item>
      </Form>
    </Modal>
  )
}

export default City

在这里插入图片描述
可以在 onCreate 函数请求后端的接口,将填写的数据保存在数据库中。

在这里插入图片描述

import React, { useState, useEffect } from 'react'
import { Card, Button, Table, Form, Select, Modal, Input, message, Pagination } from 'antd'
import axios from '../../axios/index'
import Utils from '../../utils/utils'

const FormItem = Form.Item
const Option = Select.Option

const City = () => {
  const [visible, setVisible] = useState(false)
  const [list, setList] = useState([])
  const [pagination, setPagination] = useState(1)
  const [selectedRowKeys, setSelectedRowKeys] = useState([])
  const [isModalVisible, setIsModalVisible] = useState(false)

  const onCreate = (values) => {
    let sys_user_name = JSON.parse(localStorage.getItem('bikeCMS'))
    setVisible(false);
    axios.ajax({
      url: '/city/openCity',
      data: {
        params: {
          sys_user_name,
          ...values
        }
      }
    }).then((res) => {
      if (res.status === 200 && res.code === 0) {
        message.info(res.result);
        requestList()
      }
    })
  }

  const requestList = (pagination) => {
    axios.ajax({
      url: '/city/list',
      data: {
        params: {
          page: pagination
        }
      }
    }).then((res) => {
      let list = res.result.item_list.map((item, index) => {
        item.key = index;
        return item;
      });
      setList(list)
    })
  }

  useEffect(() => {
    requestList(pagination)
  }, [pagination])

  const columns = [
    {
      title: '城市ID',
      dataIndex: 'id'
    }, {
      title: '城市名称',
      dataIndex: 'name'
    }, {
      title: '用车模式',
      dataIndex: 'mode',
      render(mode) {
        return mode === 1 ? '停车点' : '禁停区';
      }
    }, {
      title: '营运模式',
      dataIndex: 'op_mode',
      render(op_mode) {
        return op_mode === 1 ? '自营' : '加盟';
      }
    }, {
      title: '授权加盟商',
      dataIndex: 'franchisee_name'
    }, {
      title: '城市管理员',
      dataIndex: 'city_admins',
      render(arr) {
        return arr.map((item) => {
          return item;
        }).join(' , ');
      }
    }, {
      title: '城市开通时间',
      dataIndex: 'open_time',
      render: Utils.formateDate
    }, {
      title: '操作时间',
      dataIndex: 'update_time',
      render: Utils.formateDate
    }, {
      title: '操作人',
      dataIndex: 'sys_user_name'
    }
  ]

  const onSelectChange = (selectedRowKeys) => {
    console.log('selectedRowKeys changed: ', selectedRowKeys);
    setSelectedRowKeys(selectedRowKeys)
    showModal()
  };

  const rowSelection = {
    selectedRowKeys,
    onChange: onSelectChange,
  };

  const paginationChange = (pagination) => {
    setPagination(pagination)
  }

  const showModal = () => {
    setIsModalVisible(true);
  };

  const handleOk = () => {
    let delDataId = list[selectedRowKeys]
    console.log(delDataId)
    setIsModalVisible(false);
  };

  const handleCancel = () => {
    setIsModalVisible(false);
  };
  return (
    <div style={{ width: '100%' }}>
      <Card style={{ marginTop: 10, paddingTop: 15 }}>
        <Button
          type="primary"
          onClick={() => {
            setVisible(true);
          }}
        >
          开通城市
        </Button>
      </Card>
      <Card>
        <div className="content-wrap">
          <Table
            bordered
            columns={columns}
            dataSource={list}
            pagination={false}
            rowSelection={rowSelection}
          />
          <div className="pagination" style={{ float: 'right', marginTop: 20 }}>
            <Pagination onChange={paginationChange} defaultCurrent={1} total={10 * (pagination + 1)} />
          </div>
        </div>
      </Card>
      <Modal visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
        <p>确认删除?</p>
      </Modal>
      <OpenCity
        visible={visible}
        onCreate={onCreate}
        onCancel={() => {
          setVisible(false);
        }}
      />
    </div>
  )
}

const OpenCity = ({ visible, onCreate, onCancel }) => {
  const [form] = Form.useForm()
  return (
    <Modal
      visible={visible}
      title="开通城市"
      okText="确认"
      cancelText="取消"
      onCancel={onCancel}
      onOk={() => {
        form
          .validateFields()
          .then((values) => {
            form.resetFields();
            onCreate(values);
          })
          .catch((info) => {
            console.log('Validate Failed:', info);
          });
      }}
    >
      <Form
        form={form}
        layout="vertical"
        name="form_in_modal"
        initialValues={{
          modifier: 'public',
        }}
      >
        <Form.Item
          name="id"
          label="选择城市"
          rules={[
            {
              required: true,
              message: '请选择',
            },
          ]}
        >
          <Select style={{ width: 100 }}>
            <Option value={12443}>洛阳市</Option>
            <Option value={11443}>北京市</Option>
            <Option value={14644}>厦门市</Option>
            <Option value={14643}>广州市</Option>
            <Option value={14443}>深圳市</Option>
            <Option value={14244}>柳州市</Option>
            <Option value={84244}>合肥市</Option>
            <Option value={74244}>南昌市</Option>
            <Option value={45244}>大同市</Option>
          </Select>
        </Form.Item>
        <Form.Item
          name="op_mode"
          label="营运模式"
          rules={[
            {
              required: true,
              message: '请选择',
            },
          ]}>
          <Select style={{ width: 100 }}>
            <Option value={1}>自营</Option>
            <Option value={2}>加盟</Option>
          </Select>
        </Form.Item>
        <Form.Item
          name="mode"
          label="用车模式"
          rules={[
            {
              required: true,
              message: '请选择',
            },
          ]}
        >
          <Select style={{ width: 100 }}>
            <Option value={1}>指定停车点</Option>
            <Option value={2}>禁停区</Option>
          </Select>
        </Form.Item>
        <Form.Item
          name="franchisee_name"
          label="授权加盟商"
          rules={[
            {
              required: true,
              message: '请选择',
            },
          ]}
        >
          <Input type="text" placeholder="请输入姓名" />
        </Form.Item>
        <Form.Item
          name="city_admins"
          label="城市管理员"
          rules={[
            {
              required: true,
              message: '请选择',
            },
          ]}
        >
          <Input type="text" placeholder="请输入姓名" />
        </Form.Item>
      </Form>
    </Modal>
  )
}

export default City

文章的代码有点多,都是可以直接复制粘贴看效果的。对于管理系统而言,无非都是一些表格的显示与操作。使用 UI 组件库,可以大大减少开发的时间,还是蛮方便的。


👉👉👉👉:木兰君 / 共享单车后台管理系统

关注大明贵妇公众号
在这里插入图片描述

获取 react + antd 实战视频资料(回复共享单车后台管理系统) 🎁🎁🎁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值