ant design Table实现可编辑的单元格

3 篇文章 0 订阅
3 篇文章 0 订阅

欢迎点击领取 -《前端开发面试题进阶秘籍》:前端登顶之巅-最全面的前端知识点梳理总结

*分享一个使用比较久的专线🪜

需求

在这里插入图片描述
最近接到的一个需求,在table栏中实现属性的可编辑单元格,并且table内部可动态删减的单元格,外部操作新增或删除一行新旧数据的操作,无交互的前端实现,这篇文章希望对你有帮助。

想法或思路

如何去实现这一功能,无非是数组的增删改查
1、规则模块单独抽离出来,封装成一个公共组件,实现代码的可用性,在今后的开发中,没有局限性的限制,整个团体都可以使用你开发的东西,这是一个循序渐进的过程。
2.开发了解,react 的传参机制,react组件化封装,ant design提供的api多元化的使用,不受限。
3.我的实现方法可能复杂了一点,利用了两个table实现,考虑到后期多个联动的地方,未使用ant design里面的form来实现,form实现同理。

代码展示:

主界面,定义我们的初始化界面
import TableFromList from '../Component/TableFromList';
state = {
	dataSource: [{  // 初始化我们的数据保证有一条数据渲染
	key: 0,
	dataList: [{
		name: '',
		age: '',
		selected: '',
		needAdd: true,
		needRemove: true,
	}], 
	age: '',
	needAdd: true,
	needRemove: true,
	}]
}
render() {
	return (
	<Card bordered={false} title="活动参与条件">
          {getFieldDecorator('plans', { // 使用getFieldDecorator用于进行双向绑定,存取我们需要的value
            initialValue: dataSource, // 设定我们的初始值,模块化的开发,
            // 让我们更有利的维护我们的开发成本,只需要维护当前主界面
          })(<TableFromList />)} // 自定义组件名称
        </Card>
	)
}
模块化公共组件式开发,先封装我们的内部增删改查,也可外用的组件。
import React, { PureComponent } from 'react';
import {
  Table,
  Icon,
  Select,
} from 'antd';
import styles from './style.less';

const { Option } = Select;

const columns = (props) => {
  const { handleChange, handleAdd, handleRemove } = props;
  return [{
    dataIndex: 'name',
    width: 120,
    render: (text, record, index) => {
      return (
        <Select
          allowClear
          value={text}
          style={{ width: '100%' }}
          placeholder="请选择"
          onChange={(value) => { handleChange(value, 'name', index); }}
        >
          <Option key={1} value={1}>名字</Option>
          <Option key={2} value={2}>年龄</Option>
          <Option key={3} value={3}>性别</Option>
        </Select>
      );
    },
  }, {
    dataIndex: 'age',
    key: 'age',
    width: 120,
    render: (text, record, index) => {
      return (
        <Select
         value={text}
          style={{ width: '100%' }}
          placeholder="请选择"
          onChange={(value) => { handleChange(value, 'age', index); }}
        >
          <Option key={1} value={1}>名字</Option>
          <Option key={2} value={2}>年龄</Option>
          <Option key={3} value={3}>性别</Option>
        </Select>
      );
    },
  }, {
    dataIndex: 'selected',
    key: 'selected',
    width: 120,
    render: (text, record, index) => {
      return (
        <Select
         value={text}
          style={{ width: '100%' }}
          placeholder="请选择"
          mode="multiple"
          onChange={(value) => { handleChange(value, 'selected', index); }}
        >
           <Option key={1} value={1}>名字</Option>
          <Option key={2} value={2}>年龄</Option>
          <Option key={3} value={3}>性别</Option>
        </Select>
      );
    },
  }, {
    dataIndex: 'delete',
    key: 'delete',
    width: 10,
    render: (text, record) => {
      const arr = [];
      if (record.needAdd) {
        arr.push(
          <Icon
            key="add"
            type="plus-circle"
            onClick={() => handleAdd(record.key)}
            style={{ fontSize: '16px', cursor: 'pointer' }}
          />,
        );
      }
      if (record.needRemove) {
        arr.push(
          <Icon
            key="edit"
            onClick={() => handleRemove(record.key)}
            type="minus-circle"
            style={{ fontSize: '16px', cursor: 'pointer', paddingLeft: '10px' }}
          />,
        );
      }
      return arr;
    },
  }];
};

export default class DataListFrom extends PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      dataSource: props.value, // 用于接收父组件传过来的参数
    };
  }

  componentWillReceiveProps(nextProps) {
    if ('value' in nextProps) {
      this.setState({
        dataSource: nextProps.value,  // 通过改变props给数组赋值
      });
    }
  }

  handleChange = (value, name, index) => { // 依据需求而定,各个选择框可实现联动
    const newValue = value;
    const { onChange } = this.props;
    const { dataSource } = this.state;
    dataSource[index][name] = newValue;
    const newDataSource = dataSource.map(item => ({ ...item }));
   onChange(newDataSource);
  };

  handleAdd = (key) => {
    const { dataSource } = this.state;
    const newData = dataSource.map(item => ({ ...item, needAdd: false, needRemove: true })); // 后端返回存储数据
    newData.push({
      key: key + 1, // 声明唯一的key值,保证数据不污染
      name: '',
      age: '',
      selected: '',
      needAdd: true,
      needRemove: true,
    });
    this.setState({
      dataSource: newData,
    });
  }

  handleRemove = (key) => { // 删除的显示依据你的需求而定
    const { dataSource } = this.state;
    const newData = dataSource.filter(item => item.key !== key);
    newData[newData.length - 1] = Object.assign(
      {},
      newData[newData.length - 1],
      { needAdd: true, needRemove: true },
    );
    if (newData.length === 1) {
      newData[0] = Object.assign({}, newData[0], { needAdd: true, needRemove: false });
    }
    this.setState({
      dataSource: newData,
    });
  }

  render() {
    const { dataSource } = this.state;
    return (
      <Table
        className={styles.TableHeaderCss}
        columns={columns({
          handleAdd: this.handleAdd,
          handleChange: this.handleChange,
          handleRemove: this.handleRemove,
        })}
        pagination={false}
        showHeader={false} // 去除我们的title。
        dataSource={dataSource}
      />
    );
  }
}

最外层子组件封装同理,同上。
import DataListFrom from './DataListFrom'; // 引入我们封装好的子组件
其他原理不变,只需在我们的columns对应的头下render的时候使用<DataListFrom value={text} />即可。
实现的方式很多,并不单单只有我这种,有兴趣的同学可以花时间研究一下。
  • 5
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SunnyRun!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值