npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@uiw/react-table

v4.22.3

Published

Table component

Downloads

1,054

Readme

Table 表格

Buy me a coffee Open in unpkg NPM Downloads npm version

表示两种相互对立的状态间的切换,多用于触发「开/关」。选中时的内容支持响应式。

import { Table } from 'uiw';
// or
import Table from '@uiw/react-table';

基本使用

import React from 'react';
import { Table, Button } from 'uiw';

const columns = [
  {
    // title: '姓名',
    ellipsis: true,
    title: ({ key }) => {
      return (
        <span>字段: {key}</span>
      )
    },
    key: 'name', 
  }, {
    title: '年龄',
    style: { color: 'red' },
    key: 'age',
  }, {
    title: '地址',
    key: 'info',
  }, {
    title: '操作',
    key: 'edit',
    width: 98,
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <Button size="small" type="success">修改</Button>
      </div>
    ),
  },
];
const dataSource = [
  { name: '邓紫棋', age: '12', info: '又名G.E.M.,原名邓诗颖,1991年8月16日生于中国上海,中国香港创作型女歌手。', edit: '' },
  { name: '李易峰', age: '32', info: '1987年5月4日出生于四川成都,中国内地男演员、流行乐歌手、影视制片人', edit: '' },
  { name: '范冰冰', age: '23', info: '1981年9月16日出生于山东青岛,中国影视女演员、制片人、流行乐女歌手', edit: '' },
  { name: '杨幂', age: '34', info: '1986年9月12日出生于北京市,中国内地影视女演员、流行乐歌手、影视制片人。', edit: '' },
  { name: 'Angelababy', age: '54', info: '1989年2月28日出生于上海市,华语影视女演员、时尚模特。', edit: '' },
  { name: '唐嫣', age: '12', info: '1983年12月6日出生于上海市,毕业于中央戏剧学院表演系本科班', edit: '' },
  { name: '吴亦凡', age: '4', info: '1990年11月06日出生于广东省广州市,华语影视男演员、流行乐歌手。', edit: '' },
];
const Demo = () => (
  <div>
    <Table bordered columns={columns} data={dataSource} />
  </div>
);
export default Demo

表头分组

表头分组通过 columns 数组中对象的 children 来实现,以渲染分组表头。。

import React from 'react';
import { Table, Button } from 'uiw';

const columns = [
  {
    title: '姓名',
    style: { color: 'red' },
    key: 'name', 
    children: [
       {
        title: '英文名字',
        width: 100,
        key: 'name_en',
      },
      {
        title: '中文名字',
        key: 'cnname',
        children:[
          {
            title: '姓名',
            style: { color: 'red' },
            key: 'firstname',
            children:[
              { title: '姓', key: 'name1', width: 80 },
              { title: '名',  key: 'name2', width: 80 },
            ]
          }, {
            title: '拼音',
            key: 'lastname',
            children:[
              { title: '姓', key: 'pinyin1', width: 80 },
              { title: '名', key: 'pinyin2', width: 80 },
            ],
          },
        ],
      }, 
    ]
  }, {
    title: '其它',
    key: 'other',
    children:[
      { title: '生日', key: 'birthday', width: 150 },
      { title: '职业', key: 'job', width: 150 },
    ],
  }, {
    title: '操作',
    key: 'edit',
    width: 150,
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <span>{text} {key} - {rowNumber} - {columnNumber}</span>
      </div>
    ),
  },
];
const dataSource = [
  { name1: '邓', name2:'紫棋', pinyin1: 'deng', pinyin2: 'ziqi', name_en: 'G.E.M.', birthday: '1991年8月16日', job: '唱作歌手、作曲人', edit:'' },
  { name1: '周', name2:'杰伦', pinyin1: 'zhou', pinyin2: 'jielun', name_en: 'Jay Chou', birthday: '1979年1月18日', job: '歌手、音乐人', edit:'' },
  { name1: '邓', name2:'紫棋', pinyin1: 'deng', pinyin2: 'ziqi', name_en: 'G.E.M.', birthday: '1991年8月16日', job: '唱作歌手、作曲人', edit:'' },
  { name1: '周', name2:'杰伦', pinyin1: 'zhou', pinyin2: 'jielun', name_en: 'Jay Chou', birthday: '1979年1月18日', job: '歌手、音乐人', edit:'' },
];
const Demo = () => (
  <div>
    <Table bordered columns={columns} data={dataSource} />
  </div>
);
export default Demo

表格行/列合并

表头只支持列合并,使用 columns 里的 colSpan 进行设置。表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。

import React from 'react';
import { Table, Button } from 'uiw';

const columns = [
  {
    title: '姓名',
    key: 'name', 
  }, {
    title: '年龄',
    style: { color: 'red' },
    key: 'age',
    colSpan: 2,
    render: (text, key, rowData, rowNum, colNum) => {
      const obj = {
        children: text,
        props: {}
      }
      if (rowNum === 0) {
        obj.props.rowSpan = 2;
      }
      if (rowNum === 1) {
        obj.props.rowSpan = 0;
      }
      return obj;
    }
  }, {
    title: '地址',
    key: 'info',
    colSpan: 0,
  }, {
    title: '操作',
    key: 'edit',
    width: 98,
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <Button size="small" type="success">修改</Button>
      </div>
    ),
  },
];
const dataSource = [
  { name: '邓紫棋', age: '12', info: '又名G.E.M.,原名邓诗颖,1991年8月16日生于中国上海,中国香港创作型女歌手。', edit: '' },
  { name: '李易峰', age: '12', info: '1987年5月4日出生于四川成都,中国内地男演员、流行乐歌手、影视制片人', edit: '' },
  { name: '范冰冰', age: '23', info: '1981年9月16日出生于山东青岛,中国影视女演员、制片人、流行乐女歌手', edit: '' },
  { name: '杨幂', age: '34', info: '1986年9月12日出生于北京市,中国内地影视女演员、流行乐歌手、影视制片人。', edit: '' },
];
const Demo = () => (
  <div>
    <Table bordered columns={columns} data={dataSource} />
  </div>
);
export default Demo

标题页脚

添加表格边框线,页头和页脚的展现效果。

import React from 'react';
import { Table, Button } from 'uiw';

const columns = [
  {
    title: '姓名',
    style: { color: 'red' },
    key: 'name', 
  }, {
    title: '年龄',
    key: 'age',
  }, {
    title: '地址',
    key: 'info',
  }, {
    title: '操作',
    key: 'edit',
    width: 98,
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <Button size="small" type="success">修改</Button>
      </div>
    ),
  },
];
const dataSource = [
  { name: '邓紫棋', age: '12', info: '又名G.E.M.,原名邓诗颖,1991年8月16日生于中国上海,中国香港创作型女歌手。', edit: '' },
  { name: '李易峰', age: '32', info: '1987年5月4日出生于四川成都,中国内地男演员、流行乐歌手、影视制片人', edit: '' },
  { name: '范冰冰', age: '23', info: '1981年9月16日出生于山东青岛,中国影视女演员、制片人、流行乐女歌手', edit: '' },
  { name: '杨幂', age: '34', info: '1986年9月12日出生于北京市,中国内地影视女演员、流行乐歌手、影视制片人。', edit: '' },
  { name: 'Angelababy', age: '54', info: '1989年2月28日出生于上海市,华语影视女演员、时尚模特。', edit: '' },
  { name: '唐嫣', age: '12', info: '1983年12月6日出生于上海市,毕业于中央戏剧学院表演系本科班', edit: '' },
  { name: '吴亦凡', age: '4', info: '1990年11月06日出生于广东省广州市,华语影视男演员、流行乐歌手。', edit: '' },
];
const Demo = () => (
  <div>
    <Table
      title={(
        <div>
          这里是标题,有边框,<b>bordered=true</b>
        </div>
      )}
      footer={(
        <div>
          这里是页脚 Footer,有边框,<b>bordered=true</b>
        </div>
      )}
      bordered columns={columns} data={dataSource} />
    <Table title="这里是标题,没有边框" footer="这里是页脚 Footer,没有边框" columns={columns} data={dataSource} />
  </div>
);
export default Demo

点击单元格

import React from 'react';
import { Table, Button, Notify } from 'uiw';

const columns = [
  {
    title: '姓名',
    style: { color: 'red' },
    key: 'name', 
  }, {
    title: '年龄',
    key: 'age',
  }, {
    title: '地址',
    key: 'info',
  }, {
    title: '操作',
    key: 'edit',
    width: 98,
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <Button size="small" type="success">修改</Button>
      </div>
    ),
  },
];
const dataSource = [
  { name: '邓紫棋', age: '12', info: '又名G.E.M.,原名邓诗颖,1991年8月16日生于中国上海,中国香港创作型女歌手。', edit: '' },
  { name: '李易峰', age: '32', info: '1987年5月4日出生于四川成都,中国内地男演员、流行乐歌手、影视制片人', edit: '' },
  { name: '范冰冰', age: '23', info: '1981年9月16日出生于山东青岛,中国影视女演员、制片人、流行乐女歌手', edit: '' },
  { name: '杨幂', age: '34', info: '1986年9月12日出生于北京市,中国内地影视女演员、流行乐歌手、影视制片人。', edit: '' },
  { name: 'Angelababy', age: '54', info: '1989年2月28日出生于上海市,华语影视女演员、时尚模特。', edit: '' },
  { name: '唐嫣', age: '12', info: '1983年12月6日出生于上海市,毕业于中央戏剧学院表演系本科班', edit: '' },
  { name: '吴亦凡', age: '4', info: '1990年11月06日出生于广东省广州市,华语影视男演员、流行乐歌手。', edit: '' },
];
const Demo = () => (
  <div>
    <Table
      title="表内容 tbody 单元格点击回调事件"
      onCell={(rowData, { rowNum, colNum }) => {
        console.log('-->3', rowData);
        console.log('-->4', rowNum);
        console.log('-->5', colNum);
        Notify.info({ description: `你点击了"${rowData.name}"。` });
      }}
      columns={columns}
      data={dataSource}
    />
    <Table
      title="表头单元格点击回调事件"
      onCellHead={(rowData, rowNum, columnNumber) => {
        console.log('-->3', rowData);
        console.log('-->4', rowNum);
        console.log('-->5', columnNumber);
        Notify.info({ description: `你点击了"${rowData.title}"。` });
      }}
      onCell={(rowData, { rowNum, colNum }) => {
        console.log('-->3', rowData);
        console.log('-->4', rowNum);
        console.log('-->5', colNum);
        Notify.info({ description: `你点击了"${rowData.name}"。` });
      }}
      columns={columns}
      data={dataSource}
    />
  </div>
);
export default Demo

原始HTML

import React from 'react';
import { Table, Button } from 'uiw';

const Demo = () => (
  <div>
    <Table bordered>
      <thead>
        <tr>
          <th>名称</th>
          <th>数量</th>
          <th>详情</th>
          <th>价格</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>土豆</td>
          <td>18</td>
          <td>2009/01/12</td>
          <td>¥86,000</td>
        </tr>
        <tr>
          <td>萝卜</td>
          <td>18</td>
          <td>2009/01/12</td>
          <td>¥86,000</td>
        </tr>
        <tr>
          <td>香蕉</td>
          <td>18</td>
          <td>2009/01/12</td>
          <td>¥86,000</td>
        </tr>
        <tr>
          <td>芝麻</td>
          <td>18</td>
          <td>2009/01/12</td>
          <td>¥86,000</td>
        </tr>
      </tbody>
    </Table>
    <Table>
      <caption>没有边框</caption>
      <thead>
        <tr>
          <th>名称</th>
          <th>数量</th>
          <th>详情</th>
          <th>价格</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>土豆</td>
          <td>18</td>
          <td>2009/01/12</td>
          <td>¥86,000</td>
        </tr>
        <tr>
          <td>萝卜</td>
          <td>18</td>
          <td>2009/01/12</td>
          <td>¥86,000</td>
        </tr>
        <tr>
          <td>香蕉</td>
          <td>18</td>
          <td>2009/01/12</td>
          <td>¥86,000</td>
        </tr>
        <tr>
          <td>芝麻</td>
          <td>18</td>
          <td>2009/01/12</td>
          <td>¥86,000</td>
        </tr>
      </tbody>
    </Table>
  </div>
);
export default Demo

选择和操作

import React from 'react';
import { Table, Button, Checkbox, Pagination, Loader } from 'uiw';

class Demo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      // 选中的 key
      checked: [],
      loading: false,
      dataSource: [
        { name: '邓紫棋', age: '12', info: '又名G.E.M.,原名邓诗颖,1991年8月16日生于中国上海,中国香港创作型女歌手。' },
        { name: '李易峰', age: '32', info: '1987年5月4日出生于四川成都,中国内地男演员、流行乐歌手、影视制片人' },
        { name: '范冰冰', age: '23', info: '1981年9月16日出生于山东青岛,中国影视女演员、制片人、流行乐女歌手' },
        { name: '杨幂', age: '34', info: '1986年9月12日出生于北京市,中国内地影视女演员、流行乐歌手、影视制片人。' },
        { name: 'Angelababy', age: '54', info: '1989年2月28日出生于上海市,华语影视女演员、时尚模特。' },
        { name: '唐嫣', age: '12', info: '1983年12月6日出生于上海市,毕业于中央戏剧学院表演系本科班' },
        { name: '吴亦凡', age: '4', info: '1990年11月06日出生于广东省广州市,华语影视男演员、流行乐歌手。' },
      ],
      columns: [
        {
          title: (data, rowNum, colNum) => {
            const indeterminate = this.state.dataSource.length !== this.state.checked.length && this.state.checked.length > 0;
            const checked = this.state.dataSource.length === this.state.checked.length;
            return (
              <Checkbox
                checked={checked}
                indeterminate={indeterminate}
                onClick={(evn) => {
                  let checked = this.state.dataSource.map((item, idx) => idx);
                  if(!evn.target.checked) {
                    checked = [];
                  }
                  this.setState({ checked });
                }}
              />
            );
          },
          key: 'checked',
          render: (text, key, rowData, rowNumber, columnNumber) => {
            return (
              <Checkbox checked={rowData.checked} onClick={this.onClickCheckedItem.bind(this, rowNumber)} />
            );
          }
        }, {
          title: '名字',
          key: 'name',
        }, {
          title: '年龄',
          key: 'age',
        }, {
          title: '地址',
          key: 'info',
        },
      ]
    }
  }
  onClickCheckedItem(rowNumber, env) {
    let { checked } = this.state;
    const isChecked = env.target.checked;
    if(isChecked) {
      // 添加到选中数组中
      checked.push(rowNumber)
      checked = checked.sort((a, b) => a - b);
    } else {
      // 删除选中项
      checked.splice(checked.indexOf(rowNumber), 1);
    }
    this.setState({ checked });
  }
  render() {
    const { checked } = this.state;
    const dataSource = this.state.dataSource.map((item, idx) => {
      const isChecked = checked.indexOf(idx) > -1;
      return { checked: isChecked, ...item };
    });
    return (
      <div>
        <Loader loading={this.state.loading} style={{ display: 'block' }}>
          <Table
            columns={this.state.columns}
            data={dataSource}
            footer={
              <Pagination
                current={2}
                pageSize={10}
                total={30}
                divider
                onChange={(current, total, pageSize) => {
                  this.setState({ loading: true });
                  const timer = setTimeout(() => {
                    // 模拟变更数据
                    const dataSource = this.state.dataSource.map(item => {
                      item.age = Number(item.age) + current;
                      return item;
                    });
                    // 翻页 API 获取数据
                    this.setState({ checked: [], dataSource, loading: false });
                  }, 2000);
                }}
              />
            }
          />
        </Loader>
      </div>
    );
  }
}
export default Demo

自定义单元格省略提示

import React from 'react';
import { Table, Button, Notify, Tooltip } from 'uiw';

const columns = [
  {
    title: 'Name',
    key: 'name',
    render: text => <a>{text}</a>,
    width: 150,
  },
  {
    title: 'Age',
    key: 'age',
    width: 80,
  },
  {
    title: 'Address',
    key: 'address',
    ellipsis: true,
    render: address => (
      <Tooltip placement="topLeft" content={address}>
        {address}
      </Tooltip>
    ),
  },
  {
    title: 'Long Column Long Column Long Column',
    key: 'address',
    ellipsis: true,
    render: address => (
      <Tooltip placement="topLeft" content={address}>
        {address}
      </Tooltip>
    ),
  },
  {
    title: 'Long Column Long Column',
    key: 'address',
    ellipsis: true,
    render: address => (
      <Tooltip placement="topLeft" content={address}>
        {address}
      </Tooltip>
    ),
  },
  {
    title: 'Long Column',
    key: 'address',
    ellipsis: true,
    render: address => {
      return (
        <Tooltip placement="topLeft" content={address}>
          {address}
        </Tooltip>
      )
    },
  },
];

const data = [
  { name: '邓紫棋', age: '12', address: '又名G.E.M.,原名邓诗颖,1991年8月16日生于中国上海,中国香港创作型女歌手。' },
  { name: '李易峰', age: '32', address: '1987年5月4日出生于四川成都,中国内地男演员、流行乐歌手、影视制片人' },
  { name: '范冰冰', age: '23', address: '1981年9月16日出生于山东青岛,中国影视女演员、制片人、流行乐女歌手' },
  { name: '杨幂', age: '34', address: '1986年9月12日出生于北京市,中国内地影视女演员、流行乐歌手、影视制片人。' },
  { name: 'Angelababy', age: '54', address: '1989年2月28日出生于上海市,华语影视女演员、时尚模特。' },
  { name: '唐嫣', age: '12', address: '1983年12月6日出生于上海市,毕业于中央戏剧学院表演系本科班' },
  { name: '吴亦凡', age: '4', address: '1990年11月06日出生于广东省广州市,华语影视男演员、流行乐歌手。' },
];

const Demo = () => (
  <div>
    <Table
      title="表内容 tbody 单元格点击回调事件"
      columns={columns}
      data={data}
    />
  </div>
);
export default Demo

无数据状态

import React from 'react';
import { Table, Button, Empty } from 'uiw';

const columns = [
  {
    ellipsis: true, 
    title: '姓名',
    key: 'name', 
  }, {
    title: '年龄',
    key: 'age',
  }, {
    title: '地址',
    key: 'info',
  }, {
    title: '操作',
    key: 'edit',
    width: 98,
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <Button size="small" type="success">修改</Button>
      </div>
    ),
  },
];
const dataSource = [];
const Demo = () => (
  <div>
    <Table
      columns={columns}
      data={dataSource}
      empty={<Empty />}  
    />
  </div>
);
export default Demo

可展开

import React from 'react';
import { Table, Button, Icon } from 'uiw';

const columns = [
  {
    title: '姓名',
    ellipsis: true, 
    key: 'name', 
  }, 
  {
    title: '年龄',
    style: { color: 'red' },
    key: 'age',
  }, 
  {
    title: '操作',
    key: 'edit',
    width: 98,
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <Button size="small" type="success">修改</Button>
      </div>
    ),
  },
];
const dataSource = [
  { name: '邓紫棋', age: '10', id: '1'},
  { name: '李易峰', age: '32', id: '2'},
  { name: '范冰冰', age: '23', id: '3'},
];
const Demo = () => (
  <div>
    <Table 
      rowKey="id"
      expandable={{
        expandedRowRender: (record, index, expanded)=>{
          return <div>{record.name}</div>
        },
        // defaultExpandAllRows: true,
        rowExpandable: (r)=>r.name!=='李易峰',
        expandIcon: (expanded) => expanded ? <Icon type="minus-circle-o"/> : <Icon type="plus-circle-o"/>,
        defaultExpandedRowKeys: ["1"]
      }}
      columns={columns} 
      data={dataSource} 
    />
  </div>
);
export default Demo

树形数据展示

表格支持树形数据的展示,当数据中有 children 字段时会自动展示为树形表格,如果不需要或配置为其他字段可以用 childrenColumnName 进行配置。

可以通过设置 indentSize 以控制每一层的缩进宽度

import React from 'react';
import { Table, Button, Icon } from 'uiw';

const columns = [
  {
    title: '姓名',
    ellipsis: true, 
    key: 'name', 
  }, 
  {
    title: '年龄',
    style: { color: 'red' },
    key: 'age',
  }, 
  {
    title: '操作',
    key: 'edit',
    width: 98,
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <Button size="small" type="success">修改</Button>
      </div>
    ),
  },
];
const dataSource = [
  { 
    name: '邓紫棋', 
    age: '10', 
    id: '1', 
    children: [
      {
        name: '邓紫棋-0-1', 
        age: '10', 
        id: '1-1', 
        children: [
          { 
            name: '邓紫棋-0-1-1', 
            age: '10', 
            id: '1-1-1',
            children: [
              {name: '邓紫棋-0-1-1-1', age: '10', id: '-0-1-1-1'},
              {name: '邓紫棋-0-1-1-2', age: '10', id: '-0-1-1-2'},
              {name: '邓紫棋-0-1-1-3', age: '10', id: '-0-1-1-3'},
            ]
          },
          { name: '邓紫棋-0-1-2', age: '10', id: '1-1-2',}
        ]
      },
      {name: '邓紫棋-0-2', age: '10', id: '1-1'},
      {name: '邓紫棋-0-3', age: '10', id: '1-1'},
    ]
  },
  { name: '李易峰', age: '32', id: '2',},
  { name: '范冰冰', age: '23', id: '3', 
    children: [
      {name: '范冰冰0-1', age: '23', id: '3-1'},
      {name: '范冰冰0-2', age: '23', id: '3-2'},
      {name: '范冰冰0-3', age: '23', id: '3-3'},
    ]
  },
];
const Demo = () => {
  const [expandedRowKeys, setExpandedRowKeys] = React.useState([])
  return (
    <div>
      <Table 
        rowKey="id"
        columns={columns}
        data={dataSource}
      />
    </div>
  )
};
export default Demo

表格列过宽导致 footer 滑动出表格底部

使用 scroll 属性给表格设置宽(x)或高(y)即可

import React from 'react';
import { Table, Button } from 'uiw';

const columns = [
  {
    // title: '姓名',
    ellipsis: true,
    title: ({ key }) => {
      return (
        <span>字段: {key}</span>
      )
    },
    key: 'name', 
  }, {
    title: '年龄',
    style: { color: 'red' },
    key: 'age',
  }, {
    title: '地址',
    key: 'info',
  }, {
    title: '操作',
    key: 'edit',
    width: 98,
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <Button size="small" type="success">修改</Button>
      </div>
    ),
  },
];
const dataSource = [
  { name: '邓紫棋', age: '12', info: '又名G.E.M.,原名邓诗颖,1991年8月16日生于中国上海,中国香港创作型女歌手。', edit: '' },
  { name: '李易峰', age: '32', info: '1987年5月4日出生于四川成都,中国内地男演员、流行乐歌手、影视制片人', edit: '' },
  { name: '范冰冰', age: '23', info: '1981年9月16日出生于山东青岛,中国影视女演员、制片人、流行乐女歌手', edit: '' },
  { name: '杨幂', age: '34', info: '1986年9月12日出生于北京市,中国内地影视女演员、流行乐歌手、影视制片人。', edit: '' },
  { name: 'Angelababy', age: '54', info: '1989年2月28日出生于上海市,华语影视女演员、时尚模特。', edit: '' },
  { name: '唐嫣', age: '12', info: '1983年12月6日出生于上海市,毕业于中央戏剧学院表演系本科班', edit: '' },
  { name: '吴亦凡', age: '4', info: '1990年11月06日出生于广东省广州市,华语影视男演员、流行乐歌手。', edit: '' },
];
const Demo = () => (
  <div>
    <Table 
      scroll={{x: 1800, y: 300}}
      footer={<div style={{height: 20, }}>这个是footer</div>}
      columns={columns} data={dataSource} 
    />
  </div>
);
export default Demo

固定列

通过使用 fixed 使其列固定

⚠️ 注意: 若并没有 scroll 滚动条,fixed 属性并不会有直观的效果

import React from 'react';
import { Table, Button } from 'uiw';

const columns = [
  {
    title: '姓名',
    ellipsis: true, 
    // fixed: true,
    width: 400,
    key: 'name', 
  }, {
    // fixed: true,
    title: '年龄',
    style: { color: 'red' },
    width: 400,
    key: 'age',
  }, {
    title: '地址',
    key: 'info',
    width: 400,
  }, {
    title: '操作',
    key: 'edit',
    width: 98,
    fixed: 'right',
    render: (text, key, rowData, rowNumber, columnNumber) => (
      <div>
        <Button size="small" type="danger">删除</Button>
        <Button size="small" type="success">修改</Button>
      </div>
    ),
  },
];
const dataSource = [
  { name: '邓紫棋', age: '12', info: '又名G.E.M.,原名邓诗颖,1991年8月16日生于中国上海,中国香港创作型女歌手。', edit: '' },
  { name: '李易峰', age: '32', info: '1987年5月4日出生于四川成都,中国内地男演员、流行乐歌手、影视制片人', edit: '' },
  { name: '范冰冰', age: '23', info: '1981年9月16日出生于山东青岛,中国影视女演员、制片人、流行乐女歌手', edit: '' },
  { name: '杨幂', age: '34', info: '1986年9月12日出生于北京市,中国内地影视女演员、流行乐歌手、影视制片人。', edit: '' },
  { name: 'Angelababy', age: '54', info: '1989年2月28日出生于上海市,华语影视女演员、时尚模特。', edit: '' },
  { name: '唐嫣', age: '12', info: '1983年12月6日出生于上海市,毕业于中央戏剧学院表演系本科班', edit: '' },
  { name: '吴亦凡', age: '4', info: '1990年11月06日出生于广东省广州市,华语影视男演员、流行乐歌手。', edit: '' },
];
const Demo = () => (
  <div>
    <Table scroll={{x: 1200}} bordered columns={columns} data={dataSource} />
  </div>
);
export default Demo

可编辑

利用 render 属性, 传递自定义组件实现

import React from 'react';
import { Table, Button, Input, Select } from 'uiw';

const columns = (onChange) => [
  {
    title: '姓名',
    ellipsis: true, 
    key: 'name', 
    render: (text,key, rowData) => {
      return <EditInput 
        value={text} 
        onChange={(value)=>{
          onChange({...rowData, name: value}, rowData.id)
        }} 
      />
    }
  }, 
  {
    title: '性别',
    key: 'gender',
    render: (text,key, rowData) => {
      return <EditInput 
        value={text} 
        component="Select"
        onChange={(value)=>{
          onChange({...rowData, gender: value}, rowData.id)
        }} 
      />
    }
  },
  {
    title: '年龄',
    key: 'age',
    render: (text,key, rowData) => {
      return <EditInput 
        value={text} 
        type="number"
        onChange={(value)=>{
          onChange({...rowData, age: value}, rowData.id)
        }} 
      />
    }
  }, 
  {
    title: '地址',
    key: 'info',
    render: (text,key, rowData) => {
      return <EditInput 
        value={text} 
        onChange={(value)=>{
          onChange({...rowData, info: value}, rowData.id)
        }} 
      />
    }
  }, 
];
const dataSource = [
  { id: 1, gender: "男", name: '邓紫棋', age: '12', info: '又名G.E.M.,原名邓诗颖,1991年8月16日生于中国上海,中国香港创作型女'},
  { id: 2, gender: "男", name: '李易峰', age: '32', info: '1987年5月4日出生于四川成都,中国内地男演员、流行乐歌手、影视制片人', },
  { id: 3, gender: "男", name: '范冰冰', age: '23', info: '1981年9月16日出生于山东青岛,中国影视女演员、制片人、流行乐女歌手', },
  { id: 4, gender: "男", name: '杨幂', age: '34', info: '1986年9月12日出生于北京市,中国内地影视女演员、流行乐歌手、影视制片人。'},
  { id: 5, gender: "男", name: 'Angelababy', age: '54', info: '1989年2月28日出生于上海市,华语影视女演员、时尚模特。', },
  { id: 6, gender: "男", name: '唐嫣', age: '12', info: '1983年12月6日出生于上海市,毕业于中央戏剧学院表演系本科班', },
  { id: 7, gender: "男", name: '吴亦凡', age: '4', info: '1990年11月06日出生于广东省广州市,华语影视男演员、流行乐歌手。', },
];
const EditInput = ({edit, value, type, onChange, component, ...other}) => {
  const [isEdit, setIsEdit] = React.useState(edit);
  const inputRef = React.useRef();
  React.useEffect(()=>{
    isEdit && inputRef.current.focus()
  }, [isEdit])
  if(isEdit) {
    if(component === "Select") {
      return <Select 
        ref={inputRef}
        defaultValue={value} 
        onBlur={e=>{
          onChange(e.target.value)
          setIsEdit(false)
        }}
      >
        <Select.Option value="男">男</Select.Option>
        <Select.Option value="女">女</Select.Option>
      </Select>
    }
    return <Input 
      {...other}
      defaultValue={value} 
      ref={inputRef} 
      type={type || "text"}
      onBlur={(e)=>{
        onChange(e.target.value)
        setIsEdit(false)
      }}
    />
  }
  return <div onClick={()=>{
    setIsEdit(true)
  }}>{value}</div>
}
const Demo = () => {
  const [data, setData] = React.useState(dataSource)
  const onChange = (value, id) => {
    setData(data.map(it=>it.id === id ? value : it))
  }
  return <div>
    <Table columns={columns(onChange)} data={data} />
  </div>
};
export default Demo

可编辑行

利用 Form 组件和 render 属性, 实现编辑行效果

import React from 'react';
import { Table, Button, Input, Select, Form, Notify } from 'uiw';

const columns = (actived, setChange, fields) => {
  return [
    {
      title: '姓名',
      ellipsis: true, 
      key: 'name', 
      render: (text,key, rowData) => {
        if(rowData.id === actived) return fields.name
        return text
      }
    }, 
    {
      title: '性别',
      key: 'gender',
      render: (text,key, rowData) => {
        if(rowData.id === actived) return fields.gender
        return text
      }
    },
    {
      title: '年龄',
      key: 'age',
      render: (text,key, rowData) => {
        if(rowData.id === actived) return fields.age
        return text
      }
    }, 
    {
      key: 'id',
      render: (id, key, rowData)=>{
        const flag = id === actived
        if(flag){
          return <>
            <Button type="primary" htmlType="submit">Save</Button>
            <Button type="danger" onClick={()=>setChange({})}>Cancel</Button>
          </>
        }
        return <Button 
          type="primary" 
          onClick={(e)=>{
            e.preventDefault();
            setChange(rowData)
          }} 
          disabled={actived !== undefined && !flag}
        >Edit</Button>
      }
    }
  ]
};
const dataSource = [
  { id: 1, gender: "男", name: '邓紫棋', age: '12', },
  { id: 2, gender: "男", name: '李易峰', age: '32', },
  { id: 3, gender: "男", name: '范冰冰', age: '23',  },
  { id: 4, gender: "男", name: '杨幂', age: '34',},
  { id: 5, gender: "男", name: 'Angelababy', age: '54', },
  { id: 6, gender: "男", name: '唐嫣', age: '12', },
  { id: 7, gender: "男", name: '吴亦凡', age: '4', },
];
const Demo = () => {
  const [data, setData] = React.useState(dataSource)
  const [itemRowData, setItemRowData] = React.useState({})
  const [id, setId] = React.useState()
  
  const form = React.useRef()
  const setChange = (rowData) => {
    setId(rowData.id)
    setItemRowData(rowData)
    form.current.setFields(rowData)
  }

  return <Form
    ref={form}
    onSubmit={({ current }) => {
      if(JSON.stringify(itemRowData) === JSON.stringify(current)) {
        Notify.error({
          title: '提交失败!',
          description: `表单提交内容并没有修改!`,
        });
        return 
      }
      setData(data.map(it=>it.id === current.id ? current : it))
      setId(undefined)
      Notify.success({
        title: '提交成功!',
        description: '数据已经更新'
      });
    }}
    fields={{
      name: {
        children: <Input placeholder="请输入姓名" />
      },
      age: {
        children: <Input placeholder="请输入年龄" type="number" />
      },
      gender: {
        children: <Select>
          <Select.Option value="男">男</Select.Option>
          <Select.Option value="女">女</Select.Option>
        </Select>
      }
    }}
  >
    {({ fields }) => <Table columns={columns(id, setChange, fields)} data={data} />}
  </Form>
};
export default Demo

Props

Table

| 参数 | 说明 | 类型 | 默认值 | |--------- |-------- |--------- |-------- | | columns | 表格列的配置描述,可以内嵌 children,以渲染分组表头。| ColumnProps[] | [] | | data | 数据数组。| Array[] | [] | | title | 表格标题 | ~~Function(text, key, rowData, rowNumber, columnNumber)~~ / Function(data: IColumns, rowNum: Number, colNum: Number)@3.0.0+ / String / ReactNode | - | | footer | 表格尾部 | String/ReactNode | - | | bordered | 是否展示外边框和列边框 | Boolean | - | | empty | 无数据状态 | ReactNode | - | | onCellHead | 表头单元格点击回调 | ~~Function(text, key, rowData, rowNumber, columnNumber)~~ / Function(data: IColumns, colNum: Number, rowNum: Number, evn: React.MouseEvent<HTMLTableCellElement>) @3.0.0+ | - | | onCell | 单元格点击回调 | ~~Function(text, key, rowData, rowNumber, columnNumber)~~ / Function(data: IColumns, options:{ colNum: Number, rowNum: Number, keyName: String }, evn: React.MouseEvent<HTMLTableCellElement>) @3.1.0+ | - | | expandable | 可展开配置 | ExpandableType | - | | rowKey | 表格行 key 的取值 | String | - | | scroll | 表格是否可滚动,也可以指定滚动区域的宽、高 | { x?: React.CSSProperties['width'], y?: React.CSSProperties['height'] } | - |

ColumnProps

列描述数据对象,是 columns 中的一项,

| 参数 | 说明 | 类型 | 默认值 | 版本 | |--------- |-------- |--------- |-------- |-------- | | title | 列头显示文字。| ReactNode | - | - | | key | 需要的 key,可以忽略这个属性,如果标题带有 render 函数,那么这个 key 为必须非常重要。| String | - | - | | width | 列宽度。| Number | - | - | | colSpan | 合并表头行。| Number | - | - | | ellipsis | 超过宽度将自动省略。v4.8.7+| Boolean | false | - | | render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前值的 key,行索引数据,当前行号,当前列号。| Function(text, key, rowData, rowNumber, columnNumber) | - | - | | align | 设置列的对齐方式 | "left"|"center"|"right" | - | - | | className | 列样式类名 | String | - | - | | fixed | 把选择框列固定 | Boolean |"left"|"right" | - | 4.15.1 |

expandable

⚠️ 注意: expandedRowKeys 与 onExpandedRowsChange 必须同时出现或不出现

| 参数 | 说明 | 类型 | 默认值 | |--------- |-------- |--------- |-------- | | expandedRowRender | 自定义展开行| (record, index, expanded) => React.ReactNode | - | | expandIcon | 自定义图标 | (expanded, record, index) => React.ReactNode; | - | | rowExpandable | 是否允许展开| (record)=>Boolean | - | | defaultExpandAllRows | 初始时,是否展开所有行| Boolean | false | | defaultExpandedRowKeys | 初始时,默认展开的行 rowKey数组 | Array | - | | expandedRowKeys | 控制展开的行 rowKey数组 | Array | - | | onExpandedRowsChange | 展开的行变化触发 | (expandedRows)=>void | - | | onExpand | 点击展开图标触发 | (expanded,record,index)=>void | - | | indentSize | 控制树形结构每一层的缩进宽度 | Number | 16 | | childrenColumnName | 指定树形结构的列名 | String | children |