ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

React使用antd对于复杂数据类型表的渲染

2021-10-15 09:06:20  阅读:208  来源: 互联网

标签:const name price 数据类型 number results React secondType antd


React使用antd对于复杂数据类型表的渲染

数据

 const table = [
      {
        firstType: '电器',
        results: [
          {
            secondType: '电视',
            list: [
              {
                name: '小米',
                number: 20,
                price: 800
              },
              {
                name: '长虹',
                number: 10,
                price: 500
              }
            ]
          },
          {
            secondType: '冰箱',
            list: [
              {
                name: '美的',
                number: 20,
                price: 1000
              },
              {
                name: '海尔',
                number: 10,
                price: 888
              }
            ]
          }
        ]
      },
      {
        firstType: '食物',
        results: [
          {
            secondType: '零食',
            list: [
              {
                name: '坚果',
                number: 50,
                price: 8
              },
              {
                name: '辣条',
                number: 80,
                price: 3
              }
            ]
          },
          {
            secondType: '生疏',
            list: [
              {
                name: '青菜',
                number: 100,
                price: 1
              }
            ]
          }
        ]
      }
    ]

方法1:表格行列合并

image-20211012092454059

思路:将复杂的嵌套数据转换一条条的各自独立的数据,当其有相同的元素 对其合并

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

const spanTable = () => {
  const [tableData, setTableData] = useState<any[]>([])

  const getTableData = () => {
    const table = [
      {
        firstType: '电器',
        results: [
          {
            secondType: '电视',
            list: [
              {
                name: '小米',
                number: 20,
                price: 800
              },
              {
                name: '长虹',
                number: 10,
                price: 500
              }
            ]
          },
          {
            secondType: '冰箱',
            list: [
              {
                name: '美的',
                number: 20,
                price: 1000
              },
              {
                name: '海尔',
                number: 10,
                price: 888
              }
            ]
          }
        ]
      },
      {
        firstType: '食物',
        results: [
          {
            secondType: '零食',
            list: [
              {
                name: '坚果',
                number: 50,
                price: 8
              },
              {
                name: '辣条',
                number: 80,
                price: 3
              }
            ]
          },
          {
            secondType: '生疏',
            list: [
              {
                name: '青菜',
                number: 100,
                price: 1
              }
            ]
          }
        ]
      }
    ]

    setTableData(handleSpan(table))
  }

  // 表格合并方法
  const handleSpan = (table, type = 3) => {
    const newData: any[] = []
    // 合并
      // 处理合并表格数据
      table.map((item, i) => {
        if (item.results && item.results.length) {
          item.results.map((ss, si) => {
            if (ss.list && ss.list.length) {
              ss.list.map((tt, ti) =>{
                const newItem = {
                  index: i + 1,
                  id: Math.floor(Math.random() * 100),//可以引入 nanoid组件生成不重复的id
                  firstType: item.firstType,
                  secondType: ss.secondType,
                  ...tt
                }
                // 三级合并的行数,所有子级results的长度
                if (si === 0 && ti === 0) {
                  newItem.oneRowSpan = item.results.reduce((a, b) => {
                    // console.log(a, b)
                    return a + b.list.length
                  }, 0)
                }
                // 二级合并的行,当前子级list的长度
                if (ti === 0) {
                  newItem.twoRowSpan = ss.list.length
                }

                newData.push(newItem)
              })
            }
          })
        }
      })
    
    console.log(newData)
    return newData
  }

  useEffect(() => {
    getTableData()
  }, [])

  const colums = [
    {
      title: '排序',
      dataIndex: 'index',
      render: (value, row) => {
        const obj = {
          children: value,
          props: {
            rowSpan: 0
          },
        };
        // 三级合并
        if (row.oneRowSpan) {
          obj.props.rowSpan = row.oneRowSpan;
        }
        return obj;
      },
    },
    {
      title: '一级分类',
      dataIndex: 'firstType',
      render: (value, row) => {
        const obj = {
          children: value,
          props: {
            rowSpan: 0
          },
        };
        // 三级合并
        if (row.oneRowSpan) {
          obj.props.rowSpan = row.oneRowSpan;
        }

        return obj;
      },
    },
    {
      title: '二级分类',
      dataIndex: 'secondType',
      render: (value, row) => {
        const obj = {
          children: value,
          props: {
            rowSpan: 0
          },
        };
        // 二级合并
        if (row.twoRowSpan) {
          obj.props.rowSpan = row.twoRowSpan;
        }
        return obj;
      },
    },
    {
      title: '名称',
      dataIndex: 'name',
    },
    {
      title: '数量',
      dataIndex: 'number',
    },
    {
      title: '价格',
      dataIndex: 'price',
    },
  ]


  return (
    <div>
      <h3 style={{marginTop: '15px'}}>表格合并</h3>
      <Table
        bordered
        columns={colums}
        rowKey="id"
        dataSource={tableData}
        pagination={false}
       />
    </div>
  )
}

export default spanTable

缺点:当负载类型数据量很大时 不便对于数据进行分析

方法二:使用嵌套子表格对于数据渲染

嵌套子表格

image-20211012095708312

image-20211012100148041

代码

  • 可以运用方法一的方法,将数据类型修改成如下处理:

      const table: any =[
        {
          firstType: '电器',
          secondType: '电视',
          results: [
            {
              name: '小米',
              number: 20,
              price: 800
            },
            {
              name: '长虹',
              number: 10,
              price: 500
            }
           ]
        },
        {
          firstType: '电器',
          secondType: '冰箱',
          results: [
            {
              name: '美的',
              number: 20,
              price: 1000
            },
            {
              name: '海尔',
              number: 10,
              price: 888
            },
          ]
        },
        {
          firstType: '食物',
          secondType: '零食',
          results: [
            {
              name: '坚果',
              number: 50,
              prie: 8
            },
            {
              name: '辣条',
              number: 80,
              price: 3
            }
            ]
          },
          {
            firstType: '食物',
            secondType: '生疏',
            results: [
                {
                  name: '青菜',
                  number: 100,
                  price: 1
                }
              ]
            },
          ]
    
import React, { useEffect, useState } from 'react';
import { Table} from 'antd'
export default () => {
 
  const dataSource: any = [
    {
      key: '1',
      title: '餐饮酒店/服务员',
      number: '8家门店,共8人',
      time: '2020.05.25 15:35',
      childData: [
        {
          key: '1.1',
          jobTitle: '大桶大足浴-保安',
          num: '2人',
        },
        {
          key: '1.2',
          jobTitle: '大桶大足浴-保安',
          num: '5人',
        },
      ]
    },
    {
      key: '2',
      title: '餐饮酒店/收银员',
      number: '无门店,共5人',
      time: '2020.06.06 11:35',
      childData: [
        {
          key: '2.1',
          jobTitle: '大桶大足浴',
          num: '0人',
        },
        {
          key: '2.2',
          jobTitle: '大桶大足浴',
          num: '1人',
        },
      ]
    },
  ]
  const table: any =[
    {
      firstType: '电器',
      secondType: '电视',
      results: [
        {
          name: '小米',
          number: 20,
          price: 800
        },
        {
          name: '长虹',
          number: 10,
          price: 500
        }
       ]
    },
    {
      firstType: '电器',
      secondType: '冰箱',
      results: [
        {
          name: '美的',
          number: 20,
          price: 1000
        },
        {
          name: '海尔',
          number: 10,
          price: 888
        },
      ]
    },
    {
      firstType: '食物',
      secondType: '零食',
      results: [
        {
          name: '坚果',
          number: 50,
          prie: 8
        },
        {
          name: '辣条',
          number: 80,
          price: 3
        }
        ]
      },
      {
        firstType: '食物',
        secondType: '生疏',
        results: [
            {
              name: '青菜',
              number: 100,
              price: 1
            }
          ]
        },
      ]


  const parentColumns: any = [
    {
      title: '第一类',
      dataIndex: 'firstType',
      key: 'firstType',
    },
    {
      title: '第二类',
      dataIndex: 'secondType',
      key: 'secondType',
    },
  ]
  const expandedRowRender = (record: any, index: any, indent: any, expanded: any) => {
    const childData = record.results
    const childColumns: any = [
      {
        title: <span style={{ color: "green" }}>名称</span>,
        dataIndex: 'name',
        key: 'name'
      },
      {
        title: <span style={{ color: "green" }}>数量</span>,
        dataIndex: 'number',
        key: 'number'
      },
      {
        title: <span style={{ color: "green" }}>价格</span>,
        dataIndex: 'price',
        key: 'price'
      },
    ]
   
    return <Table columns={childColumns} dataSource={childData} pagination={false} />
  }


  return (
    <div>
      <Table columns={parentColumns} dataSource={table} expandable={{ expandedRowRender }}/>
    </div>
  );
}

暂时只能理解到这两种方法,但数据量增大的化,还是不够理想

标签:const,name,price,数据类型,number,results,React,secondType,antd
来源: https://blog.csdn.net/qq_45749061/article/details/120776580

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有