antd的Table组件实现单元格可编辑

目录

 官网做法

其他做法


首先,官网文档上是有可编辑单元格和可编辑行的。我研究了好几遍,也是半知半解,只会用

antd的Table组件实现单元格可编辑_第1张图片

 官网做法

  • 有一定的局限性,单元格内只能是输入框(我试了一些别的,不太行)

代码直接照着文档粘贴,只说一下需要改动的地方

table的数据源,我们都是后端获取,所以这里把默认的清空就行。请求接口获取数据源,直接set进去就行

antd的Table组件实现单元格可编辑_第2张图片

 然后记得给 Table 标签添加 rowKey 属性,绑定唯一值

antd的Table组件实现单元格可编辑_第3张图片

 如果想单元格可编辑,记得添加   editable: true,

antd的Table组件实现单元格可编辑_第4张图片

 下面是我自己练习的一个案例

import { Form, Input, Popconfirm, Table, Button } from 'antd'
import React, { useContext, useEffect, useRef, useState } from 'react'
import './Lll.css'
import axios from 'axios'

const EditableContext = React.createContext(null)
const EditableRow = ({ index, ...props }) => {
  const [form] = Form.useForm()
  return (
    
) } const EditableCell = ({ title, editable, children, dataIndex, record, handleSave, ...restProps }) => { const [editing, setEditing] = useState(false) const inputRef = useRef(null) const form = useContext(EditableContext) useEffect(() => { if (editing) { inputRef.current.focus() } }, [editing]) const toggleEdit = () => { setEditing(!editing) form.setFieldsValue({ [dataIndex]: record[dataIndex], }) } const save = async () => { try { const values = await form.validateFields() toggleEdit() handleSave({ ...record, ...values, }) } catch (errInfo) { console.log('Save failed:', errInfo) } } let childNode = children if (editable) { childNode = editing ? ( ) : (
{children}
) } return {childNode} } const Lll = () => { const [dataSource, setDataSource] = useState([]) const handleDelete = (key) => { const newData = dataSource.filter((item) => item.key !== key) setDataSource(newData) } const defaultColumns = [ { title: '标题', dataIndex: 'title', width: '30%', editable: true, ellipsis: true, }, { title: '分类', dataIndex: 'tab', editable: true, width: '20%', }, { title: '浏览量', dataIndex: 'reply_count', editable: true, width: '20%', }, { title: 'operation', dataIndex: 'operation', render: (_, record) => dataSource.length >= 1 ? ( handleDelete(record.key)} > 删除 ) : null, }, ] const handleSave = (row) => { const newData = [...dataSource] const index = newData.findIndex((item) => row.key === item.key) const item = newData[index] newData.splice(index, 1, { ...item, ...row, }) setDataSource(newData) } const components = { body: { row: EditableRow, cell: EditableCell, }, } const columns = defaultColumns.map((col) => { if (!col.editable) { return col } return { ...col, onCell: (record) => ({ record, editable: col.editable, dataIndex: col.dataIndex, title: col.title, handleSave, }), } }) // 点击收集 const shouji = () => { console.log('收集到的值为', dataSource) } // 初始化操作 useEffect(() => { axios .get('https://cnodejs.org/api/v1/topics') .then((res) => { setDataSource(res.data.data) }) .catch((err) => console.log(err)) }, []) return (
'editable-row'} bordered dataSource={dataSource} columns={columns} rowKey={(record) => record.id} /> ) } export default Lll

其他做法

  • 主要是用到了数据驱动视图的思想,只要数据变了,视图自然更新。需要什么标签,render里就写什么
  • render属性的值是个函数,默认有三个参数,第一个参数是当前行渲染的数据,第二个参数是后端返回给我们的完整的当前行数据,第三个参数是索引
  • 加的有校验,不想加校验就把Form相关的去掉就行
import React, { useState } from 'react'
import { Space, Table, Input, Button, DatePicker, Form } from 'antd'
import moment from 'moment'

export default function Mmm() {
  const [form] = Form.useForm()
  const columns = [
    {
      title: '标题',
      dataIndex: 'title',
      key: 'title',
      render: (_, record, index) => (
        
           upTitle(e, index)} />
        
      ),
    },
    {
      title: '时间',
      dataIndex: 'time',
      key: 'time',
      render: (_, record, index) => (
        
           upTime(time, index)} />
        
      ),
    },
    {
      title: '操作',
      key: 'action',
      render: (_, record, index) => (
        
          
        
      ),
    },
  ]
  const [data, setData] = useState([
    {
      id: 0,
      title: '标题1',
      time: '2023-03-13',
    },
    {
      id: 1,
      title: '标题2',
      time: '2023-03-14',
    },
  ])

  // 标题修改后失焦
  const upTitle = (e, index) => {
    let newArr = JSON.parse(JSON.stringify(data))
    newArr[index].title = e.target.value
    setData(newArr)
  }
  // 时间选择后
  const upTime = (time, index) => {
    let newArr = JSON.parse(JSON.stringify(data))
    newArr[index].time = time?.format('YYYY-MM-DD') || ''
    setData(newArr)
  }
  // 点击删除
  const delItem = (index) => {
    let newArr = JSON.parse(JSON.stringify(data))
    newArr.splice(index, 1)
    setData(newArr)
  }
  // 点击收集数据按钮
  const getData = () => {
    form.validateFields().then((res) => {
      // console.log(res)
      console.log('收集到的数据为', data)
    })
  }

  return (
    
record.id} /> ) }

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