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

这篇具有很好参考价值的文章主要介绍了antd的Table组件实现单元格可编辑。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

 官网做法

其他做法


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

antd 可编辑table,javascript,前端,react.js

 官网做法

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

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

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

antd 可编辑table,javascript,前端,react.js

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

antd 可编辑table,javascript,前端,react.js

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

antd 可编辑table,javascript,前端,react.js

 下面是我自己练习的一个案例文章来源地址https://www.toymoban.com/news/detail-595740.html

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 (
    <Form form={form} component={false}>
      <EditableContext.Provider value={form}>
        <tr {...props} />
      </EditableContext.Provider>
    </Form>
  )
}
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 ? (
      <Form.Item
        style={{
          margin: 0,
        }}
        name={dataIndex}
        rules={[
          {
            required: true,
            message: `${title} is required.`,
          },
        ]}
      >
        <Input ref={inputRef} onPressEnter={save} onBlur={save} />
      </Form.Item>
    ) : (
      <div
        className="editable-cell-value-wrap"
        style={{
          paddingRight: 24,
        }}
        onClick={toggleEdit}
      >
        {children}
      </div>
    )
  }
  return <td {...restProps}>{childNode}</td>
}
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 ? (
          <Popconfirm
            title="确定删除吗?"
            onConfirm={() => handleDelete(record.key)}
          >
            <a>删除</a>
          </Popconfirm>
        ) : 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 (
    <div>
      <Table
        components={components}
        rowClassName={() => 'editable-row'}
        bordered
        dataSource={dataSource}
        columns={columns}
        rowKey={(record) => record.id}
      />
      <Button onClick={shouji}>收集值</Button>
    </div>
  )
}
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) => (
        <Form.Item
          name={'title' + record.id}
          rules={[
            {
              required: true,
              message: '不能为空!',
            },
          ]}
          initialValue={record.title}
        >
          <Input onBlur={(e) => upTitle(e, index)} />
        </Form.Item>
      ),
    },
    {
      title: '时间',
      dataIndex: 'time',
      key: 'time',
      render: (_, record, index) => (
        <Form.Item
          name={'time' + record.id}
          rules={[
            {
              required: true,
              message: '不能为空!',
            },
          ]}
          initialValue={moment(record.time, 'YYYY-MM-DD')}
        >
          <DatePicker onChange={(time) => upTime(time, index)} />
        </Form.Item>
      ),
    },
    {
      title: '操作',
      key: 'action',
      render: (_, record, index) => (
        <Space size="middle">
          <Button onClick={() => delItem(index)}>删除</Button>
        </Space>
      ),
    },
  ]
  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 (
    <div>
      <Form form={form}>
        <Table
          columns={columns}
          dataSource={data}
          rowKey={(record) => record.id}
        />
      </Form>
      <Button onClick={getData}>收集数据</Button>
    </div>
  )
}

到了这里,关于antd的Table组件实现单元格可编辑的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue2 - Antd Table组件的头部单元格 字体加粗, 文字内容居中 解决办法:

    问题:默认情况下,英文字体加粗,中文字体不加粗, 在当前.vue的style增加穿透antd table的表头样式,然后在使用table的外层设置加上class 分2种情况,单独设置表头,或者所有单元格都居中 单独设置表头:在设置列时,加上方法:customHeaderCell 所有单元格:在设置第一列时加

    2024年02月15日
    浏览(44)
  • vue+antd——table组件实现动态列+表头下拉选择功能——技能提升

    展示行列数据。 当有大量结构化的数据需要展现时; 当需要对数据进行排序、搜索、分页、自定义操作等复杂行为时。 最近在写 vue+antd 的框架,遇到一个需求:就是要实现 table 表格的动态列,并且相应的表头要实现下拉选择的效果,最后点击保存时,要将下拉的内容拼接

    2024年02月09日
    浏览(40)
  • react使用antd的table组件,实现点击弹窗显示对应列的内容

    特别提醒:不能在table的columns的render里面设置弹窗组件渲染,因为这会导致弹窗显示的始终是最后一行的内容,因为这样渲染的结果是每一行都会重新渲染一遍这个弹窗并且会给传递一个content的值,渲染到最后一行的时候,就传递的是最后一行的值。这就导致你有多少行数据

    2024年02月12日
    浏览(31)
  • antd组件的Table,点击某一行,让这行整体变色

    用到了Table的rowClassName属性和onRow属性 首先说rowClassName 它的值是一个函数,参数有两个,第一个是当前行数据,第二个是索引 再说onRow  onRow也有两个参数,第一个参数是当前行数据,第二个参数是这行所对应的索引  核心思想就是,通过onRow里面的事件(我们这里用点击事件

    2024年02月13日
    浏览(24)
  • 【Vue/element】 el-table实现表格动态新增/插入/删除 表格行,可编辑单元格

    效果如下: 点击“新增一行”可以在表格最后新增一行,单元格内容可编辑 点击绿色+按钮,可在指定行的后面插入一行 点击红色-按钮,可以删除指定行 原理:表格 el-table 是通过动态循环 tableData 生成,只要对 tableData 数组进行增加删除元素,就可以达到效果 这里用了ele

    2024年02月16日
    浏览(49)
  • vxe-table表格合并单元格和编辑

    //这是在vue上面引用vxe-table插件实现的,主要方法都设置在table中,mergeCells,tableData都是在vue页面的data初使化数据, :footer-method=“footerMethod”:尾部数据,:merge-footer-items=“mergeCells”:尾部合并单元格。vxe-table网址:https://vxetable.cn/#/table/advanced/footerSpan

    2023年04月09日
    浏览(33)
  • antd+Vue 3实现table行内upload文件图片上传【超详细图解】

    目录 一、背景 二、效果图 三、代码 一名被组长逼着干前端的苦逼后端,在一个晴天霹雳的日子,被要求前端订单产品实现上传产品图片并立刻回显图片。

    2024年04月11日
    浏览(28)
  • vue+ElementUI el-table表格单元格编辑增加键盘事件功能(向上、向下、回车键盘事件)

    1、如果单元格编辑使用了插槽功能,需要在插槽上添加一个class(这个类即:当前列的porp值) 2、porp不能重复(正常也不会存在) GitHub源码地址 Gitee源码地址 基于ElementUi或Antd再次封装基础组件文档 TTable组件封装地址

    2024年02月11日
    浏览(53)
  • React学习时,自己拟定的一则小案例(table表格组件,含编辑)

    某次在Uniapp群看到有人问uniapp如何操作dom元素。 他想对这张表标红的区域,做dom元素获取,因为产品想让红色色块点击时,成为可编辑,渲染1~4月份之间的行程安排。 于是,有小伙伴说让他用position定位这里,点击时使红色色块层级抬高,弄个input上去。 但提问的小伙伴并没

    2024年02月07日
    浏览(25)
  • vant-ui的SwipeCell 滑动单元格组件 在table中使用只占用一格

    项目场景:需要在table表格中实现一个可以滑动单行,展示操作按钮。eg:qq信息界面的左划出现删除。 提示:vant-ui的SwipeCell 滑动单元格组件 在table中使用只占用一格 例如:直接用SwipeCell包含所有td则只对映表头中的第一列: 因为vant ui组件库的SwipeCell 滑动单元格组件是一个

    2024年02月11日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包